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) ?
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:
- Conditional Love: FOREACH Redux
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.
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.
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.
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.
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&)