I'm a bit confused about C temporaries in regards to string literals and move semantics.
Which one of the following is better, in terms of performance and readability.
Usage: Constructor("string_literal")
Option 1: s
is created from the string literal, then it is moved into the member variable.
Constructor(
string s
) : s_(std::move(s)) {}
Option 2: The string literal is created as a temporary, then bound to s
, then moved into the member s_
.
Constructor(
string&& s
) : s_(std::move(s)) {}
Option 3: Pass lvalue ref to temporary, then copy-construct s_
Constructor(
const string& s
) : s_(s)
In the case that caller passes a string literal to the constructor, seems like option 1 is slightly more efficient, since we skip rvalue ref binding and lvalue ref binding, respectively.
If caller passes a string to the constructor, then option 1 will do a copy-and-move, but option 2 forces the user to create a copy, which is then moved. The performance is identical, but the user has a slightly less friendly API for 2.
Which is the best option to go with? Thanks.
CodePudding user response:
Option 1 will copy when you have a movable string and construct and move from a literal.
Option 2 will move when you have a movable string and construct and move when you have a literal.
Option 3 is the worst as it will always copy.
As you can see Option 2 <= 1 <= 3.
Also consider
Constructor("string_literal"s)
This is a std::string
literal. So Option 2 will just move that right in.
Note: The compiler can optimize copies away as well in many cases.