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

Boost list run by bdawes at, gregod at, cpdaniel at, john at