$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Eric Niebler (eric_at_[hidden])
Date: 2008-04-05 21:15:24
Daniel Walker wrote:
> I don't know if this helps, because I don't exactly see what this has
> to do with lvalues/rvalues, but here's a make_tuple that respect the
> constness of the reference_wrapper. It plays nicely with result_of and
> apparently works with your identity and compose functors. (tested on
> gcc 3.4; the obj isn't copied)
> 
> struct make_tuple {
>     template<typename Sig> struct result;
> 
>     template<typename This, typename Arg>
>     struct result<This(Arg const&)> {
>         typedef tuple<Arg> type;
>     };
> 
>     template<typename This, typename Arg>
>     struct result<This(reference_wrapper<Arg> const&)> {
>         typedef tuple<
>             typename unwrap_reference<Arg>::type &
>         > type;
>     };
> 
>     template<class X>
>     typename result<
>         make_tuple(X const&)
>     >::type
>     operator()(X const& x) const
>     {
>         return tuple<X>(x);
>     }
> 
>     template<class X>
>     typename result<
>         make_tuple(reference_wrapper<X> const&)
>     >::type
>     operator()(reference_wrapper<X> const& x) const
>     {
>         return tuple<
>             typename unwrap_reference<X>::type &
>         >(x.get());
>     }
> };
> 
> Is this anything like what you're looking for?
Yes, it works, it's hideously ugly and complicated, and nobody writes 
function objects like this in practice. It proves my point.
> Note that there are specializations for result<> corresponding to
> exactly the way the operator()s are overloaded, and the overloads use
> result<> to specify they're return types. In a situation like this, I
> find it easier to try to keep a specific one-to-one correspondence
> between result<> specializations and overloads. It's a bit of a
> manually convention, but as you both point out, without decltype
> return type deduction can be tedious by nature.
"It's a bit of a manual convention" is precisely my point. Not only is 
it manual and tedious, but it's a convention that (hardly) nobody else 
follows. In generic code, I can't rely on some arbitrary function object 
Foo to do anything reasonable when passed a reference wrapper.
The general issue is: given an unknown binary function object F, an 
object L which is known to be an lvalue, and an object R known to be an 
rvalue, how do I invoke F in C++0x? F(L,R) might do the wrong thing with 
the rvalue, and F(ref(L),R) might not compile.
Only questions, no answers,
-- Eric Niebler Boost Consulting www.boost-consulting.com