
Eric Niebler wrote:
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.
#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