I appreciate the reply, On Jun 26, 2009, at 6:02 PM, Steven Watanabe wrote:
Strip the references of when you call result_of::invoke_function_object. You don't need to actually pass anything by value. This is just the return type calculation.
I guess my problem is that references don't seem to be preserved when setting up a function object pipeline via fold. Seems there should be a single copy construct from the return of the function object invocation to the new state object but a trace results in a couple of extra state objet copies per invoke_function_object invocation. Is there something I'm missing? Again, thanks in advance, Mike Attached is something to compile to illustrate my problem-apologies for the length. #include <boost/fusion/container/vector.hpp> #include <boost/fusion/algorithm/iteration/fold.hpp> #include <boost/fusion/functional/invocation/invoke_function_object.hpp> #include <iostream> namespace b = boost; namespace bf = boost::fusion; struct my_int { my_int(const int &_i=0) :i(_i) { std::cerr << "my_int construct with: " << i << "\n"; } my_int(const my_int &rhs) :i(rhs.i) { std::cerr << "my_int copy construct with: " << i << "\n"; } my_int & operator=(const my_int &rhs) { i = rhs.i; std::cerr << "my_int assign with: " << i << "\n"; return *this; } ~my_int(void) { std::cerr << "my_int destroy\n"; } int operator+(const int &rhs) const { return i+rhs; } int i; }; std::ostream & operator<<(std::ostream &os, const my_int &rhs) { return (os << rhs.i); } // we must return new values here struct add_1 { template <typename Sig> struct result; template <typename Self, typename T> struct result< Self(T) > { typedef bf::vector< typename b::remove_reference<T>::type,int> type; }; template <typename T> bf::vector<T,int> operator()(const T &t) const { std::cerr << "ran add_1 with: " << t << "\n"; return bf::vector<T,int>(t+1,1); } }; std::ostream & operator<<(std::ostream &os, const add_1 &rhs) { return (os << "add_1"); } // just pass through the values struct return_2 { template <typename Sig> struct result; template <class Self, typename T, typename U> struct result< Self(T,U) > { typedef bf::vector< typename b::remove_reference<T>::type, typename b::remove_reference<U>::type > type; }; template <typename T, typename U> bf::vector<T,U> operator()(const T &t, const U &u) const { std::cerr << "ran add_2 with: " << t << "," << u << "\n"; return bf::vector<T,U>(t,u); } }; std::ostream & operator<<(std::ostream &os, const return_2 &rhs) { return (os << "add_2"); } struct invoke_filter { template <typename Sig> struct result; template <class Self, typename T, typename State> struct result< Self(T,State) > { typedef typename bf::result_of:: invoke_function_object< typename b::remove_reference<T>::type, typename b::remove_reference<State>::type>::type type; }; template <typename T, typename State> typename bf::result_of:: invoke_function_object<T,State>::type operator()(T fun, const State &seq) const { std::cerr << "invoke_filter with: " << fun << "\n"; return bf::invoke_function_object(fun,seq); } }; int main() { bf::vector<add_1,return_2> seq; my_int my = 42; bf::vector<my_int> my_vec(my); std::cerr << "start\n\n"; bf::fold(seq,my_vec,invoke_filter()); std::cerr << "\nstop\n"; return 0; }