用于pre-C ++ 11的std :: bind替代方案

时间:2014-04-20 17:45:50

标签: c++ std c++03 stdbind

对于这个项目,我不能使用C ++ 11,或者添加任何其他依赖项(例如Boost)。

我想要实现的目标是:

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用于这个项目。

1 个答案:

答案 0 :(得分: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);
}

显然,您需要更改processFunction的定义以匹配指向BaseProcessor的指针/引用,并且它显然不如使用bind或lambdas那么漂亮,但是,如果你不能升级或得到提升,那就不会有一些严肃的魔法。