{x} 和 '= {x}' 初始化之间有什么区别(如果有的话)?

What is the difference, if any, between {x} and '= {x}' initialization?

本文关键字:如果 之间 初始化 什么 区别      更新时间:2023-10-16

我试图理解这两种初始化方式之间的语义差异:

Foo foo{x};
Foo foo = {x};

我很想知道以下情况的区别:

  1. CCD_ 1是CCD_
  2. Foo有一个构造函数,它接受与x类型相同的参数
  3. x不是Foo类型,但有一个转换构造函数可用
  4. x不是Foo类型,但是explicit转换构造函数是可用的

我的意思是,在每种情况下:

  1. 从概念上讲,调用了哪些构造函数
  2. 编译器通常会优化哪些构造函数调用
  3. 是否允许隐式转换
Foo foo{x};    // 1
Foo foo = {x}; // 2

1是直接列表初始化。2是复制列表初始化

假设Foo是一个类类型,那么在大多数情况下,它们在概念上或其他方面都会做完全相同的事情,只是如果在重载解析过程中选择了显式构造函数,那么#2就是格式错误的。特别是,与复制初始化不同,复制列表初始化在概念上不构造临时的。

一个例外是当CCD_ 10是类型CCD_。在这种情况下,#1等效于x2(即,直接初始化),#2等效于Foo foo = x;(即,复制初始化


*你必须写一些非常折磨人的代码才能解决这个问题。例如:

struct X
{
    X() = default;
    explicit X(X&);
    X(const X&);
};
int main() { 
    X x1;
    X x2 = {x1}; // #1
    X x3 = x1;   // #2
}

Pre-CWG1467,第1行格式错误,因为过载分辨率选择X(X&),即explicit。在CWG1467之后,explicit构造函数X(X&)没有被考虑,所以使用了X(const X&)。注意,线#2总是良好地形成并且使用CCD_ 19

相关文章: