是直接初始化还是复制初始化? [英] Is it direct-initialization or copy-initialization?

查看:104
本文介绍了是直接初始化还是复制初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以使用各种方法来初始化C ++中的对象(类或结构的实例)。某些语法引起对象的直接初始化,其他语法导致复制初始化。在编译器中启用 copy-elision 时,两者的性能相同。禁用 copy-elision 时,在选择每个实例化(复制初始化)时,每个实例化都会有一个附加的copy / move构造函数调用。

Initializing objects (instances of classes or structs) in C++ can be done in various ways. Some syntaxes evoke a direct-initialization of your object, other syntaxes lead to a copy-initialization. With copy-elision enabled in the compiler, both have identical performance. With copy-elision disabled, there is an additional copy/move constructor call upon every instantiation when you choose for the latter (copy-initialization).

结论:复制初始化可能会影响性能!

Conclusion: copy-initialization can have a performance-penalty!

来自以下问题: C ++ 11成员初始值设定项列表与类初始值设定项?我可以得出结论,这将是复制初始化语法:

From the following question: C++11 member initializer list vs in-class initializer? I can conclude that this would be copy-initialization syntax:

obj s = obj("value");

这将是直接初始化语法:

obj s{"value"};



但是这个呢:

 
But what about this one:

obj s = {"value"};

而这个:

obj s = obj{"value"};

而这个:

obj s("value");

或者这一个:

obj s = "value";






注意

Bjarne Stroustrup在他的书使用C ++进行编程,原理和实践第二版,第311页,第9.4.2节中比较了几种初始化样式(但不是全部):


NOTE
Bjarne Stroustrup compares a few initialization styles (but not all) in his book "Programming, Principles and Practice Using C++" 2nd edition, on page 311, §9.4.2:


struct Date {
    int y,m,d;                     //year, month, day
    Date(int y, int m, int d);     //check for valid date and initialize
    void add_day(int n);           //increase the Date by n days
};

...

Date my_birthday;                   //error: my_birthday not initialized
Date today{12,24,2007};             //oops! run-time error
Date last{2000,12,31};              //OK (colloquial style)
Date next = {2014,2,14};            //also OK (slightly verbose)
Date christmas = Date{1976,12,24};  //also OK (verbose style)


先生。 Stroustrup将这些不同的初始化样式呈现为相等。至少,这就是我的样子。不过,由于本书中尚未讨论这些术语,因此有些仍然可能是直接初始化,而另一些是 copy-initialization

Mr. Stroustrup presents these different initialization styles as equal. At least, that's how it looks to me. Nevertheless, it could still be possible that some are direct-initialization and others copy-initialization, since those terms are not yet discussed at that point in the book.

编辑

给定的答案会带来一些有趣的结果。

显然,这是直接初始化

obj s("value");

这是直接列表初始化

obj s{"value"};

有些人指出,这是有区别的。它们实际上有什么不同?

As some of you point out, there is a difference. In what way do they actually differ? Would the difference be noticeable in the output of a non-optimizing compiler?

推荐答案


obj s = obj("value");


这是对prvalue的直接初始化,然后将其用于复制初始化变量 s 。 C ++ 17的prvalue规则实际上对 s 进行了直接初始化。

This is direct initialization of a prvalue, which is then used to copy initialize the variable s. C++17's prvalue rules make this de-facto direct initialization of s.


obj s{"value"};


这是直接- 列表 -初始化。 列表部分很重要。任何时候为了初始化对象而应用了支撑初始化列表,都在执行列表初始化。

This is direct-list-initialization. The "list" part is important. Anytime you apply a braced-init-list for the purposes of initializing an object, you are performing list-initialization.


obj s = {"value"};


这是复制列表初始化。


obj s = obj{"value"};


这是对prvalue的直接列表初始化,即然后用于复制初始化变量 s

This is direct-list-initialization of a prvalue, which is then used to copy initialize the variable s.


obj s("value");


这是直接初始化。


obj s = "value";


这是副本初始化。


先生。 Stroustrup会以相同的方式呈现这些不同的初始化样式。

Mr. Stroustrup presents these different initialization styles as equal.

就它们在大多数情况下所做的相同而言,它们是相等的。但是他们在技术上并不平等;复制列表初始化不能调用 explicit 构造函数。因此,如果选择的构造函数是 explicit ,则在复制列表初始化的情况下代码将无法编译。

They are equal in the sense that they do mostly the same thing. But they're not technically equal; copy-list-initialization cannot call explicit constructors. So if the selected constructor were explicit, the code would fail to compile in the copy-list-initialization cases.

这篇关于是直接初始化还是复制初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆