#include <iostream>
#include <initializer_list>
using namespace std;
struct CL
{
CL(){}
CL (std::initializer_list<CL>){cout<<1;}
CL (const CL&){cout<<2;}
};
int main()
{
CL cl1;
CL cl2 {cl1}; //prints 21
}
这是带有复制构造函数和初始化列表构造函数的CL结构。我认为这里必须调用复制构造函数,因为根据 C++ 14 标准,8.5.4/3
类型 T 的对象或引用的列表初始化定义如下:
— 如果 T 是类类型并且初始化器列表具有 cv U 类型的单个元素,其中 U 是 T 或从 T 派生的类,则对象是从该元素初始化(通过复制初始化进行复制列表初始化,或通过直接初始化进行直接列表初始化)。
- 除此以外, ...
换句话说,cl2的初始化必须从cl1元素执行,而不是从初始化列表{cl1}执行。Clang 和 gcc 都打印“21”,只有 Visual Studio 打印“2”,我认为它是正确的。
有两个候选构造函数用于获取 CL 类型的参数cl1:
- 构造函数
std::initializer_list<CL>
(通过,因为没有从 CL 到 的这种转换std::initializer_list<CL>
) - 使用 const CL& 复制构造函数(仅与限定转换 non-const->const 完全匹配)
谁是对的?谁的行为是正确的?