编译器可以通过直接初始化替换复制初始化吗

时间:2015-07-19 19:01:07

标签: c++ copy-constructor

C ++ Primer (第5版)在第499页说明允许编译器替换

string null_book = "9-999-9999-9"; // copy initialization

代表

string null_book("9-999-9999-9"); // compiler omits the copy constructor

另一方面,this post表明(通常)这两种形式可以产生不同的结果。

如何协调 C ++ Primer 中的声明与引用的帖子?

2 个答案:

答案 0 :(得分:5)

本书试图用普通的C ++代码来说明复制省略。这并不意味着允许编译器将复制初始化更改为直接初始化,即使在您显示初始化的情况下,copy-initialization-with-copy-elision也具有与直接初始化相同的效果。

允许的可观察行为的唯一变化是忽略对复制/移动构造函数和析构函数的调用。调用的另一个构造函数永远不会更改。因此:

struct Meow {
    explicit Meow(int); // #1
    Meow(double);       // #2
    Meow(const Meow&);  // #3
};

Meow m = 1;     // OK, always call #2, may or may not call #3
Meow n(1);      // OK, call #1, never call #3
Meow p = {1};   // Error: copy-list-initialization selected explicit constructor
Meow q{1};      // OK, call #1, never call #3
Meow r = {1.0}; // OK, call #2, never call #3 

答案 1 :(得分:0)

是的,这是许多情况中的一种,受复制省略规则([class.copy])的约束,其中编译器可能生成临时对象但不要求这样做

正式地,当uU类型的值且T可以从U构造时,初始化T t = u;表示{{1}从t构造的临时构造构造,就像您编写了u一样。但是,此副本可能(并且通常 )被删除,效果是T t = T(u);,只有复制初始化要求构造函数是非显式的。