|
Boost Users : |
Subject: Re: [Boost-users] fusion::result_of::invoke_function_object and references
From: Mike Tegtmeyer (tegtmeye_at_[hidden])
Date: 2009-06-26 21:15:10
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;
}
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net