
Eric Niebler wrote:
int main() { int i = 0; int const j = 0; fusion::tuple<int, int &> t1 = make_pair()(1,i); fusion::tuple<int &, int> t2 = make_pair()(i,j); fusion::tuple<int &, int const &> t4 = make_pair()(boost::ref(i), boost::ref(j));
typedef boost::result_of<make_pair(int, int &)>::type p1;
typedef boost::result_of<make_pair(int &, int const &)>::type p2;
typedef boost::result_of<make_pair( boost::reference_wrapper<int> , boost::reference_wrapper<int const> )>::type p3;
using boost::is_same; BOOST_MPL_ASSERT((is_same<p1, fusion::tuple<int, int &> >)); BOOST_MPL_ASSERT((is_same<p2, fusion::tuple<int &, int> >)); BOOST_MPL_ASSERT((is_same<p3, fusion::tuple<int &, int const &> >)); }
Does `normalize_arg` mean: int -> int int & -> int & int const & -> int [*] reference_wrapper<int> -> int & reference_wrapper<int const> -> int const & I couldn't understand [*]. BTW: int i = 0; return make_pair()(i); is not safe, after all.
This has a few advantages:
* The author of make_pair doesn't need to write an exponential number of overloads to get proper rvalue/lvalue handling. That's handled in the crtp base.
* Make_pair doesn't need to worry about reference_wrappers, either.
It depends on context whether or not reference_wrapper should be unwrapped. E.g. always(boost::ref(k))(1,2,3) `always` needs to know whether or not an argument is a reference_wrapper.
* And generic code can detect if a function object F is implemented this way, and either reference-wrap lvalue arguments or else access the nested ::impl function object directly to ensure correct rvalue/lvalue argument handling.
Is this an idea worth pursuing? Can we get something like this in Egg?
If you want to specify a "capture" way, Egg provides `generator`: egg::generator< pair< egg::deduce<_1, how_to_capture>, egg::deduce<_2, how_to_capture> > >::type const make_pair = {{}}; Regards, -- Shunsuke Sogame