
Jonathan Turkanis wrote:
"Eric Niebler" <eric@boost-consulting.com> 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