3

我想在 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,那么实现它的正确方法是什么?

4

1 回答 1

3

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

不过,像 Boost.Phoenix 这样的一些库允许动态创建多态函子。例如ref(std::cout) << 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);
于 2011-07-29T08:45:02.030 回答