I would like to call a function on all elements of a boost::fusion::vector. The elements are开发者_开发知识库 of types like this:
class A {
...
void print_with_prefix(const char *prefix) {
std::cout << prefix << *this;
}
};
One can call this function on each element in this way:
// 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));
}
However, this implementation of print_all()
including helper class is pretty ugly and seems overly complicated! Assuming C++0x is allowed, what is the right way to implement it?
What you did is the right way. C++0x can't help much in that respect because e.g. lambda expressions are not polymorphic, so at the end of the day you'll have to write a template somewhere (which unfortunately must be at namespace scope, even with C++0x), like you did with the operator()
.
Some libraries like Boost.Phoenix allow to create polymorphic functors on the fly though. For instance ref(std::cout) << arg1
creates an object that is capable of passing any kind of argument to std::cout
. It won't help in your case since you're calling a member function.
It's the second time I'm mentioning it today, but I do have a make_overload
facility that allows me to create an overloaded functor on the fly. It could help in your case if the set of element types is small and not likely to change. For instance assuming there's only two such types A
and B
:
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);
精彩评论