Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-12-02 07:58:08


Eric Niebler wrote:
> Jonathan Turkanis wrote:
>
>> "Eric Niebler" <eric_at_[hidden]> wrote in:
>>
>>> Seems to me that Arkadiy has run up against the same problem with
>>> BOOST_TYPEOF_PRESERVE_LVALUE, which also gets this case wrong (according
>>> to the docs).
>>
>>
>> Yeah, that's what I was thinking about last night. I was trying to see
>> how close
>> I could approximate decltype.
>>
>
>
> Here is an interesting way to "distinguish" between L-values and
> R-values. The following program uses the properties of the conditional
> operator to implement an IS_LVALUE macro that detects the value-ness of
> an expression and prints its determination. It works with gcc 3.3.3 and
> with Comeau online, but vc7.1 doesn't like it. Alas, I haven't yet
> figured out a way to use this technique to get a compile-time constant.

#include <boost/static_assert.hpp>

typedef char yes;
typedef char (&no)[2];

template <class T>
yes is_nonconst_rvalue(T const&, ...);

template <class T>
no is_nonconst_rvalue(T&, int);

struct foo
{
     template<typename U>
     operator U () const;

     template<typename V>
     operator V & () volatile const;

     static foo const instance;
     static bool select;
};

#define IS_RVALUE(x) \
     (sizeof(is_nonconst_rvalue((foo::select ? foo::instance : (x)), 0))
== sizeof(yes))

int rvalue();
int const_rvalue();
int& lvalue();
int const& const_lvalue();

BOOST_STATIC_ASSERT(IS_RVALUE(rvalue()));
BOOST_STATIC_ASSERT(IS_RVALUE(const_rvalue()));
BOOST_STATIC_ASSERT(!IS_RVALUE(const_lvalue()));
BOOST_STATIC_ASSERT(!IS_RVALUE(const_lvalue()));

Still no dice for vc7.1, though.

-- 
Dave Abrahams
Boost Consulting
http://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