Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2004-12-02 06:19:34


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.
Maybe someone more clever than myself can figure that out.

#include <stdio.h>

struct foo
{
     template<typename U>
         operator U () const
     {
         throw "R-value";
     }

     template<typename V>
         operator V & () volatile const
     {
         throw "L-value";
     }
};

foo const f = {};

#define IS_LVALUE(x) \
     try { (true? f : (x)); } \
     catch( char const *value ) { printf("%s\n",value); }

struct bar {};

bar baz1() { static bar b; return b; }
bar const baz2() { static bar b; return b; }
bar & baz3() { static bar b; return b; }
bar const & baz4() { static bar b; return b; }

int main()
{
     bar b;
     bar const cb = {};

     // l-values
     IS_LVALUE(b);
     IS_LVALUE(cb);

     // r-values
     IS_LVALUE(baz1());
     IS_LVALUE(baz2());

     // l-values
     IS_LVALUE(baz3());
     IS_LVALUE(baz4());

     return 0;
}

-- 
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