简体   繁体   中英

What is the difference between the 3 definitions?

string var = "var";
string var2("var2");
string var3 = string("var3");

What is the difference between the 3 definitions?

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.

  1. A temporary object of type std::string is created using the string literal "var3" on the right hand side . Then, the copy/move constructor of std::string is used to construct the object named var3 from that temporary.
  2. In C++11, there isnon-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 var3 from that temporary, implementations can just directly construct var3 from "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 var3 is created directly using the string literal "var3" and a suitable std::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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM