简体   繁体   English

3个定义有什么区别?

[英]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? 3个定义有什么区别?

C++11 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.对于上面显示的语句,C++11 中有两种可能性。

  1. A temporary object of type std::string is created using the string literal "var3" on the right hand side . std::string类型的临时 object是使用右侧字符串文字"var3"创建的。 Then, the copy/move constructor of std::string is used to construct the object named var3 from that temporary.然后, std::string的复制/移动构造函数用于从该临时构造名为var3的 object。
  2. In C++11, there isnon-mandatory copy elison which means that implementations are allowed to elide the temporary on the right hand side.在 C++11 中,有非强制性的复制省略,这意味着允许实现省略右侧的临时。 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" .这意味着不是在右侧创建一个临时文件,然后使用复制/移动构造函数从该临时文件构造var3 ,实现可以直接从"var3"构造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.在上面的语句中,一个名为var2的 object 是使用字符串文字"var2"和合适的std::string的构造函数构造的。 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++11中的问题的答案是,只有在不逃避临时性的情况下,陈述之间才会存在差异。

C++17 C++17

In C++17, there is mandatory copy elison which means that in this case when we write:在 C++17 中,有强制复制 elison ,这意味着在这种情况下,当我们编写时:

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.相反, object var3是使用字符串文字"var3"和合适的std::string的构造函数直接创建的。

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.在上面的语句中,一个名为var2的 object 是使用字符串文字"var2"和合适的std::string的构造函数构造的。 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.因此,您在 C++17中的问题的答案是陈述之间没有区别

With enabled copy elision (guaranteed here since C++17), they are the same.启用复制省略(自 C++17 起在此处保证),它们是相同的。 Without it, there are additional move constructor and destructor calls in the first and third cases.没有它,在第一种和第三种情况下会有额外的移动构造函数析构函数调用。

Live demo: https://godbolt.org/z/P5Er1a1Pb现场演示: 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).主要编译器默认应用复制省略,即使禁用优化(例如在 GCC/Clang 的情况下使用-O0 )。


Note: I assume string stands for std::string .注意:我假设string代表std::string Generally, you need to check the initialization rules for different types of initialization ( direct , copy , ...) to resolve the effects.通常,您需要检查不同类型的初始化直接复制,...)的初始化规则来解决效果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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