【问题标题】:Passing/binding arguments when using boost::fusion::for_each使用 boost::fusion::for_each 时传递/绑定参数
【发布时间】:2011-07-29 08:38:34
【问题描述】:

我想在 boost::fusion::vector 的所有元素上调用一个函数。元素的类型如下:

class A {
    ...
    void print_with_prefix(const char *prefix) {
        std::cout << prefix << *this;
    }
};

可以这样对每个元素调用这个函数:

// Call print_with_prefix() on a boost::fusion sequence:

struct CallPrintWithPrefix {
    const char *prefix_;
    CallPrintWithPrefix(const char *prefix) : prefix_(prefix) {}
    template <class T> void operator()(T &element) const {
        element.print_with_prefix(prefix);
    }
}

template <class BoostFusionVector>
void print_all(BoostFusionVector &v, const char *prefix) {
    boost::fusion::for_each(v, CallPrintWithPrefix(prefix));
}

然而,print_all() 的这个实现包括帮助类是非常丑陋的,而且看起来过于复杂!假设允许 C++0x,那么正确的实现方式是什么?

【问题讨论】:

    标签: c++ foreach metaprogramming boost-fusion


    【解决方案1】:

    你所做的是正确的方法。 C++0x 在这方面无济于事,因为例如lambda 表达式不是多态的,因此最终您必须在某处编写模板(不幸的是,模板必须在命名空间范围内,即使使用 C++0x 也是如此),就像您对 operator() 所做的那样。

    一些像 Boost.Phoenix 这样的库允许动态创建多态函子。例如ref(std::cout) &lt;&lt; arg1 创建一个能够将任何类型的参数传递给std::cout 的对象。由于您正在调用成员函数,因此对您的情况没有帮助。

    这是我今天第二次提到它,但我确实有一个make_overload 工具,可以让我动态创建一个重载的仿函数。如果元素类型的集合很小并且不太可能改变,它可能会对您的情况有所帮助。例如假设只有两种这样的类型AB

    auto overload = make_overload(
        [prefix](A& a)
        { a.print_with_prefix(prefix); }
        , [prefix](B& c)
        { b.print_with_prefix(prefix); } );
    boost::fusion::for_each(v, overload);
    

    【讨论】:

    • 感谢您的解释!你的 make_overload 魔法似乎很强大! (你有它的链接吗?)在我的特殊情况下,大约有 10 种不同的类型,所以这也会很长。
    • @hrr 不,我没有公开我的 make_overload(我想我应该)。鉴于它对我的其余代码只有一个(小)依赖,我提取了它,你可以看到它here。如果您对此有任何疑问,可以加入聊天(我通常在 Room Lounge),即使我不在这里也可以给我留言。这比填满评论空间更受欢迎。
    • 代码看起来很漂亮,感谢您发布!诚然,我还不知道所有优秀的 C++0x 构造,有没有好的参考...没关系,我可能应该在 Lounge 中问这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    相关资源
    最近更新 更多