Boost logo

Boost :

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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk