4

How can you tell whether or not a given parameter is an rvalue in C++03? I'm writing some very generic code and am in need of taking a reference if possible, or constructing a new object otherwise. Can I overload to take by-value as well as by-reference and have the rvalue returns call the by-value function?

Or do I have a very sickening feeling that this is why rvalue references are in C++0x?

Edit:

is_rvalue = !(is_reference || is_pointer) ?

cHao
  • 84,970
  • 20
  • 145
  • 172
Puppy
  • 144,682
  • 38
  • 256
  • 465

5 Answers5

5

There apparently is a way to determine whether an expression is an rvalue or lvalue in C++03 (I say apparently because I'm not sure how well I understand the technique). Note that to make the technique usable, preprocessor macros are pretty much required. Eric Niebler has written a nice article about how it works and how it gets used in BOOST_FOREACH:

Note that the article is pretty heavy reading (at least it is for me); as Neibler says in it:

There's no doubt that this is arcane stuff, but we are rewarded with a robust way to detect the rvalue-ness and lvalue-ness of any expression.

Using the rvalue detection described in the artcile might help you deal with at least some of the issues that C++0x's rvalue references solve.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • 1
    [Here](http://www.artima.com/cppsource/foreach3.html) is the relevant page of the article. Interesting stuff. – academicRobot Jun 11 '10 at 19:36
  • @academicRobot: I can't believe that I forgot to actually link to the article. The link is in there now (and as you say, the rvalue detection stuff is on page 3). – Michael Burr Jun 11 '10 at 19:40
  • +1, that's a great technique, but that does the check at *run-time*. I'm trying to extend this to find out at *compile-time* whether or not the expression is an lvalue or not. I've asked a [question about this](http://stackoverflow.com/questions/9084671/c03-test-for-rvalue-vs-lvalue-at-compile-time-not-just-at-runtime). – Aaron McDaid Jan 31 '12 at 18:10
2

How can you tell whether or not a given parameter is an rvalue in C++03?

You can't. All you can do is trust your clients and cheat:

void call_me_with_anything(const T& const_ref)
{
    /* read from const_ref */
}

void call_me_with_rvalue_only_please_i_trust_you(const T& const_ref)
{
    T& ref = const_cast<T&>(const_ref);
    /* write through ref */
}

I'm writing some very generic code

Then I'm afraid C++03 won't cut it for you.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
1

Or do I have a very sickening feeling that this is why rvalue references are in C++0x?

You are correct, you need C++0x and rvalue references to do that.

The closest thing I can think of is to take something by const-reference as that can bind to either an lvalue or an rvalue (if the rvalue needs to construct a temporary it will). That said, your code will not be able to distinguish between the two.

R Samuel Klatchko
  • 74,869
  • 16
  • 134
  • 187
1

Or do I have a very sickening feeling that this is why rvalue references are in C++0x?

Yup. That is exactly why they're added to C++0x. You can't create overloads in C++ to distinguish between rvalues and lvalues.

jalf
  • 243,077
  • 51
  • 345
  • 550
0

I'm writing some very generic code and am in need of taking a reference if possible, or constructing a new object otherwise.

Won't this do what you want?

void f(T& t);
void f(T const& t);

Note that...

T t; f(t); // calls f(T&)
f(T()); // calls f(T const&)
Edward Strange
  • 40,307
  • 7
  • 73
  • 125