2014-04-20 4 views
0

이 프로젝트에서는 C++ 11을 사용할 수 없으며 추가 종속성 (예 : 부스트)을 추가 할 수 없습니다.pre-C++에 대한 std :: bind 대체 11

내가 달성하기 위해 노력하고있어입니다 :

typedef void (*processorFunction)(int numItems, std::string* items); 

class Files 
{ 
public: 
    Files() : m_KVSeparator('='), m_ListSeparator(',') {} 
    ~Files() {} 

    void ReadDataFile(std::string filename, std::map<std::string, processorFunction> processorFunctions); 

    char m_KVSeparator; 
    char m_ListSeparator; 
}; 

void Files::ReadDataFile(std::string filename, std::map<std::string, processorFunction> processorFunctions) 
{ 
    // The file parsing and choosing of the function omitted for brevity: 
    processorFunction processor = ...; 
    int numItems = ...; 
    std::string* items = ...; 

    processor(numItems, items); 
} 

// Example parser: 
void time_limit_parser(int& timeLimit, int numItems, std::string* items) 
{ 
    timeLimit = atoi(items[0].c_str()); 
} 

int main() 
{ 
    // Omitted getting the global file manager pointer 
    Files* files = ...; 
    std::map<std::string, processorFunction> configProcessorFunctions; 
    int timeLimit; 
    // ****** WHAT GOES HERE? ****** 
    files->ReadDataFile("config.dat", configProcessorFunctions); 
} 

나는 ****** WHAT GOES HERE? ****** 줄에 무엇을 넣을까요되어 내 질문? 부분적으로 적용하기 위해 std :: bind를 사용할 것입니다 (la time_limit_parser(timeLimit)). 그러나이 프로젝트에는 C++ 11을 사용할 수 없습니다.

+0

C++ 11 이전부터 TR1은 이미'std :: tr1 :: bind'를 제공했습니다. 그게 당신에게 유효합니까? 그렇지 않다면 Boost에 의존성을 추가 할 수 없더라도 Boost의 구현을 자신의 프로젝트에 복사 할 수 있습니다. – hvd

답변

1

bind은 함수 포인터를 반환하지 않기 때문에 bind으로도 원하는 것을 수행 할 수 없습니다. 대신 std::function 템플릿을 사용하여 포장해야합니다.

밝혀진 바와 같이, 당신이 그 일을 정확히하지 못하게하는 것은 아무것도 없습니다.

struct BaseProcessor 
{ 
    virtual void operator()(int numItems, std::string* items) = 0; 
}; 

struct TimeLimitParser : public BaseProcessor 
{ 
    int& timeLimit; 

    TimeLimitParser(int& limit) 
     : timeLimit(limit) 
    {} 

    virtual void operator()(int numItems, std::string* items) 
    { 
     time_limit_parser(timeLimit, numItems, items); 
    } 
}; 

int main() 
{ 
    // Omitted getting the global file manager pointer 
    Files* files = ...; 
    std::map<std::string, processorFunction*> configProcessorFunctions; 
    int timeLimit; 
    TimeLimitParser parser(timeLimit); 
    configProcessorFunctions["foo"] = &parser; 
    files->ReadDataFile("config.dat", configProcessorFunctions); 
} 

분명히 당신은 BaseProcessor에 대한 포인터/참조를 일치 processFunction의 정의를 변경해야하고, 명확하게 bind 또는 람다를 사용하는 것만 큼 꽤 아니지만, 업그레이드하거나 얻을 수없는 경우이 약의 향상 좋은 일이라면 진지한 마법을받지 않아도 될 것입니다.

+2

템플릿의 버전을 작성할 수 있으므로 유형의 순열 수에 1 버전 당 하나의 버전을 쓰는 대신 매개 변수의 수당 하나의 버전 만 작성하면됩니다. 내가 이해하는 한, 이것은 기본적으로 boost 버전이하는 것입니다. – PeterT