C++ 初始化:括号与等号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4470553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:29:09  来源:igfitidea点击:

initialization: parenthesis vs. equals sign

c++initialization

提问by fredoverflow

Possible Duplicate:
Is there a difference in C++ between copy initialization and assignment initialization?

可能的重复:
C++ 中的复制初始化和赋值初始化之间有区别吗?

What's the difference between

有什么区别

T a(b);

and

T a = b;

and

T a = T(b);

?

?

采纳答案by Cheers and hth. - Alf

T a( b );

is direct initialization, unless it parses as a function declaration, in which case it's a function declaration.

直接初始化,除非它解析为函数声明,在这种情况下它是函数声明。

T a = b;

is copy initialization, which means that it works as if a temporary object is constructed on the right hand side, and that ais then copy constructed or, in C++11 and later, possibly move constructed, from that temporary.

复制初始化,这意味着它的工作就像在右侧构造了一个临时对象,a然后复制构造,或者在 C++11 及更高版本中,可能从该临时构造移动构造。

The compiler is free to elide (remove) the temporary+copying/moving whenever it can, but a copy or move constructor, whichever would be logically used, must still be accessible and not explicit.

编译器可以随意省略(删除)临时+复制/移动,但复制或移动构造函数,无论在逻辑上使用哪一个,仍然必须是可访问的,而不是explicit.

For example, in C++03 you cannot copy-initialize a std::ostringstream, because it doesn't have a copy constructor. In C++11 you can copy-initialize an ostringstreamif the initializer is a temporary, which then results in a logical move construction (which however will usually be elided, optimized away). For example, this copy initialization declaration,

例如,在 C++03 中,您不能复制初始化 a std::ostringstream,因为它没有复制构造函数。在 C++11 中,ostringstream如果初始化程序是临时的,您可以复制初始化 an ,然后导致逻辑移动构造(但是通常会被省略,优化掉)。例如,这个副本初始化声明,

ostringstream s = ostringstream( "blah" );

… doesn't compile as C++03, because in C++03 the copy initialization invokes the class' copy constructor, which doesn't exist. It does however compile as C++11, because in C++11 the copy initialization invokes the move constructor. And while (to maintain its illusion of being a stream) a std::ostringstreamcan't be directly copied, it canbe moved.

... 不会编译为 C++03,因为在 C++03 中,复制初始化调用了类的复制构造函数,而该构造函数并不存在。然而,它确实编译为 C++11,因为在 C++11 中,复制初始化调用了移动构造函数。虽然(为了保持其作为流的错觉) astd::ostringstream不能直接复制,但可以移动。

Another such difference: in C++03 only the copy initialization syntax supports curly bracesinitializer, which in C++03 you can use when Tis an aggregate type such as a raw array. In C++11 the curly braces notation has been extended and generalized as a uniform initialization syntax, so it can be used also with direct initialization. And so the following direct initialization declaration,

另一个这样的区别:在 C++03 中,只有复制初始化语法支持花括号初始化器,在 C++03 中,您可以使用 whenT是聚合类型,例如原始数组。在 C++11 中,大括号表示法已被扩展和推广为统一的初始化语法,因此它也可以与直接初始化一起使用。所以下面的直接初始化声明,

int v[]{ 3, 1, 4, 1, 5, 9, 2, 6, 5, 4 };

… does not compile as C++03, but does compile as C++11 and later.

... 不会编译为 C++03,但会编译为 C++11 及更高版本。

The =copy initialization syntax is the original initialization syntax from C.

=副本初始化语法与C的原始初始化语法

And in C++11 and later, due to move semantics, it can be used in a much wider range of cases than in C++03, such as with a std::ostringstream.

而在 C++11 及更高版本中,由于移动语义,它可以在比 C++03 中更广泛的情况下使用,例如带有std::ostringstream.

回答by AraK

T a(b);

Calls a constructor of athat accepts b. (If bis of the same type, then the copy constructor is called).

调用a其接受的构造函数b。(如果b是相同类型,则调用复制构造函数)。

T a = b;

a temporary object of type Tis created to be constructed by b. Then the copy constructor is called(=is not an assignment in this case and the next case!).

T创建一个类型为的临时对象,由 构造b。然后调用复制构造函数(=在这种情况下和下一种情况下都不是赋值!)。

T a = T(b);

Same as above! except that we explicitly constructed a temporary object.

和上面一样!除了我们显式构造了一个临时对象。

Note that the standard allows total elimination of temporary copies in the second and third case. Also, if bis not of type T, then in the first case Tdoesn't have to have a copy constructor. In the second and third cases, even though the implementation is free to optimize the whole thing, it still requires an accessible copy constructor. IIRC the standard calls this: copy elision.

请注意,该标准允许在第二种和第三种情况下完全消除临时副本。此外,如果b不是 type T,则在第一种情况下T不必具有复制构造函数。在第二种和第三种情况下,即使实现可以自由优化整个事情,它仍然需要一个可访问的复制构造函数。IIRC 标准称之为:复制省略

回答by unquiet mind

They are all constructor calls - the = sign is just syntactic sugar. Exactly which constructors get called is to a certain extent up to the compiler.

它们都是构造函数调用——= 符号只是语法糖。究竟调用哪些构造函数在一定程度上取决于编译器。

回答by oldSkool

The = operator will invoke the default copy constructor unless the = operator is overloaded I believe... this would make a shallow copy; assigning the same member values to the first object as the right-hand operator

= 操作符将调用默认的复制构造函数,除非 = 操作符被重载我相信……这会产生一个浅拷贝;为第一个对象分配与右手运算符相同的成员值