【问题标题】:std::bind alternative for pre-C++11C++11 之前的 std::bind 替代方案
【发布时间】:2014-04-20 17:45:49
【问题描述】:

对于这个项目,我不能使用 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 来部分应用它(比如time_limit_parser(timeLimit)),但我不能在这个项目中使用 C++11。

【问题讨论】:

  • 甚至在 C++11 之前,TR1 就已经提供了std::tr1::bind。你可以使用吗?如果没有,那么即使你不能添加对 Boost 的依赖,你也可以将 Boost 的实现复制到你自己的项目中。

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


【解决方案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 漂亮,但如果您无法升级或获得提升如果没有一些严肃的巫术,这几乎是一样的好。

【讨论】:

  • 另外值得注意的是,您当然可以编写模板版本,这样您只需为每个参数数量编写一个版本,而不是每个数量乘以类型排列的一个版本。据我了解,这基本上也是 boost 版本所做的。
猜你喜欢
  • 1970-01-01
  • 2011-11-10
  • 2020-06-01
  • 2012-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
相关资源
最近更新 更多