I have a simple class:
class X
{
std::string S;
X (const std::string& s) : S(s) { }
};
I've read a bit about rvalues lately, and I've been wondering, if I should write constructor for X
using rvalue, so I would be able do detect temporary objects of std::string
type?
I think it should look something like:
X (std::string&& s) : S(s) { }
As to my knowledge, implementation of std::string in compilers supporting C++11 should use it's move constructor when available.
Rvalue references is a small technical extension to the C++ language. Rvalue references allow programmers to avoid logically unnecessary copying and to provide perfect forwarding functions. They are primarily meant to aid in the design of higer performance and more robust libraries.
“l-value” refers to a memory location that identifies an object. “r-value” refers to the data value that is stored at some address in memory. References in C++ are nothing but the alternative to the already existing variable. They are declared using the '&' before the name of the variable.
Yes, rvalues are moved, lvalues are copied. But when there's no according move operation, rvalues are copied as well.
The most common pattern you'll see when working with rvalue references is to create a move constructor and move assignment operator (which follows the same principles). A move constructor, like a copy constructor, takes an instance of an object as its argument and creates a new instance based on the original object.
X (std::string&& s) : S(s) { }
That is not a constructor taking an rvalue, but a constructor taking an rvalue-reference. You should not take rvalue-references in this case. Rather pass by value and then move into the member:
X (std::string s) : S(std::move(s)) { }
The rule of thumb is that if you need to copy, do it in the interface.
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