string var = "var";
string var2("var2");
string var3 = string("var3");
What is the difference between the 3 definitions?
CodePudding user response:
C 11
First lets consider the statement:
string var3 = string("var3"); //2 possiblities here in C 11, explained below
For the above shown statement there are 2 possibilities in C 11.
- A temporary object of type
std::stringis created using the string literal"var3"on the right hand side. Then, the copy/move constructor ofstd::stringis used to construct the object namedvar3from that temporary. - In C 11, there is non-mandatory copy elison which means that implementations are allowed to elide the temporary on the right hand side. This means instead of creating a temporary on the right hand side and then using a copy/move constructor to construct
var3from that temporary, implementations can just directly constructvar3from"var3".
The exact same explanation goes for the statement:
string var = "var";//same 2 possiblities here in C 11 as explained above
Now lets consider the statement:
string var2("var2"); // This is direct initialization in both C 11 and C 17. No possibility of creating temporary here in both C 11 and C 17
In the above statement, an object named var2 is constructed using the string literal "var2" and a suitable std::string's constructor. There is no temporary of any kind in this case.
So, the answer to your question in C 11 is that there is a difference between the statements only if the temporary is not eluded.
C 17
In C 17, there is mandatory copy elison which means that in this case when we write:
string var3 = string("var3");// only 1 possibility here in C 17. No temporary can be created.
In the above statement, the language guarantees that
No temporary on the right hand side is created. Instead, the object
var3is created directly using the string literal"var3"and a suitablestd::string's constructor.
Same goes for the statement:
string var = "var"; //only 1 possibility in C 17. No temporary created in C 17 due to mandatory copy elison
Now lets consider the statement:
string var2("var2"); //This is direct initialization in both C 11 and C 17 and there is no possibility of creating temporary in both C 11 and C 17
In the above statement, an object named var2 is constructed using the string literal "var2" and a suitable std::string's constructor. There is no temporary of any kind in this case.
So the answer to your question in C 17 is that there is no difference between the statements.
CodePudding user response:
With enabled copy elision (guaranteed here since C 17), they are the same. Without it, there are additional move constructor and destructor calls in the first and third cases.
Live demo: https://godbolt.org/z/P5Er1a1Pb
Major compilers do apply copy elision by default, even with disabled optimizations (such as with -O0 in case of GCC/Clang).
Note: I assume string stands for std::string. Generally, you need to check the initialization rules for different types of initialization (direct, copy, ...) to resolve the effects.
