The following example code compiles.
#define USE_RVALUE // line 1
template<class data_type>
class Container
{
data_type& data;
public:
#ifdef USE_RVALUE
Container(data_type&& _data) : data(_data) {}
#endif
Container(data_type& _data) : data(_data) {}
};
int main()
{
double d = 42.0;
Container<double> c1(d);
Container<double> c2(1.0f); // line 18
return 0;
}
My compiler command:
g++ -std=c++11 -Wall ref.cpp -o ref # g++ is 4.7.1
If we outcomment line 1, g++ complains:
no matching function for call to ‘Container<double>::Container(float)’
ref.cpp:18:34: note: candidates are:
ref.cpp:11:9: note: Container<data_type>::Container(data_type&) [with data_type = double]
ref.cpp:11:9: note: no known conversion for argument 1 from ‘float’ to ‘double&’
[... (more candidates)]
Of course, the error is clear, and a typical error in C++03: References from rvalues are not allowed, if these rvalues are not const. But why does it work with the rvalue constructor (i.e. the #ifdef enabled)? We have the same situation in the initializer list: Reference from non-const value.
Also, if you explain it... Is this code "good coding style" or "to avoid"?
The answer is simple enough: whatever has name - it is an lvalue. So in your ctor, with rvalue reference, _data is an lvalue in the body of ctor despite the fact it is an rvalue in the outer world. So at the end you have a dangling reference so you should not do such a thing.
Basically, when you accept something by &&(except when in template, aka Universal references) you should treat it as "this value are going to be destroyed". So you should steal from it, change it, whatever(except leaving it in some invalid state preventing its normal destruction). But you should never store pointer or reference to it. Because this object maybe destroyed right after your function complete. It is exactly the case you have. double(1.0f) exists in your ctor body only and has no meaning outside it and you still store reference to it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With