采用初始值设定项列表的构造函数
Constructors taking initializer lists
我得到了使用大括号进行统一初始化的想法。但是为什么在具有采用初始值设定项列表的构造函数的类型上使用此语法,调用该特定构造函数,即使参数仅包装在一对大括号中,即
int main(int argc, const char ** argv)
{
vector<int> vs0{3};
for(int v : vs0)
{
cout << v << ' ';
}
cout << 'n';
vector<int> vs1(3);
for(int v : vs1)
{
cout << v << ' ';
}
}
/*
Output
3
0 0 0
*/
为什么 vs0 是用初始值设定项列表构造函数构造的?不应该是
vector<int> v2{{3}};
为此?这有点令人困惑,特别是如果您不知道一个类具有采用初始值设定项列表的构造函数。
如果该类有一个构造函数采用std::initializer_list
,那么在列表初始化中传递大括号初始化列表时,它将是首选。
否则,
T
的构造函数将分两个阶段考虑:
所有将
std::initializer_list
作为唯一参数的构造函数,或者如果其余参数具有 检查默认值,并通过过载分辨率进行匹配 反对类型std::initializer_list
的单个参数如果上一阶段未产生匹配项,则
T
的所有构造函数都参与针对以下参数集的重载解析: 由大括号初始化列表的元素组成,但有限制 只允许非缩小范围的转换。如果这个阶段 生成显式构造函数作为 复制列表初始化,编译失败(注意,简单 复制初始化,根本不考虑显式构造函数(。
{3}
是一个大括号的初始化列表,那么vector
将被初始化为包含 1 个值为3
的元素。该行为与传递{1, 2}
、{1, 2, 3}
等一致。
听起来你是在寻求动力,而不是在标准中说必须这样做的地方。为此,您可以查看C++语言创建者Bjarne Stroustrup的初始列表的原始提案N1919。
他列出了四种初始化对象的方法:
X t1 = v; // “copy initialization” possibly copy construction
X t2(v); // direct initialization
X t3 = { v }; // initialize using initializer list
X t4 = X(v); // make an X from v and copy it to t4
请注意,他不是在谈论 C++11,也不是引入初始值设定项列表的提议版本。这又回到了 98 C++。大括号初始化器语法已经有效,但仅适用于 C 样式结构,即没有用户定义的构造函数。这是 C 的延续,它总是允许以这种方式初始化结构(和数组(,并且它将始终做同样的事情:逐个元素初始化。
该提案的重点在于允许以与那些 C 样式结构和数组相同的方式初始化适当的C++对象(如std::vector<int>
(:C++ 旨在允许用户定义的类看起来像内置类型(因此例如运算符重载(,而这里有一个地方它没有。为了扭转你的问题,奇怪的不是std::vector<int>{3}
调用初始化器列表构造函数,奇怪的是std::vector<std::string>{3}
调用非初始化器列表构造函数。为什么它曾经调用非初始化器列表构造函数?这并不是大括号初始化的最初用途。答案是允许使用手写构造函数的固定长度容器,如下所示:
class Vector3D {
public:
Vector3D(double x, double y, double z) { /*...*/ }
// ...
};
Vector3D v = {1, 2, 3}; // Ought to call non-initialiser list constructor
这就是为什么在使用大括号初始化时首选采用std::initializer_list
的构造函数(如果可用(。对于那些了解背景的人来说,对所有内容使用大括号初始化器似乎真的很反常:Foo f{7}
看起来f
将直接包含数字7
,并且在构造完成后没有其他内容,而不是说它做一些任意的事情,比如构造一个 7 个元素长的东西。
- 一对向量构造函数:初始值设定项列表与显式构造
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- 构造函数/函数声明参数列表中的统一初始化
- 在初始化列表之外手动调用基类的构造函数
- 采用初始值设定项列表的构造函数
- 提供初始值设定项列表构造函数的有效方法
- C 标准中是否有任何计划来解决初始化器列表构造函数的不一致性
- 接受迭代器的初始值设定项列表构造函数
- STD :: MAP初始化列表构造函数
- 如何避免丢失自动生成的初始化列表构造函数
- 如何最小化调用列表构造函数(复制构造函数)的次数?
- 初始化列表构造函数错误带有CRTP
- 启用默认初始值设定项列表构造函数
- 使用初始化列表构造函数时C++奇怪的行为
- 自定义列表类的初始值设定项列表构造函数
- 初始值设定项列表构造函数导致右值构造函数不明确
- 调用初始化列表构造函数的不同方式
- 为什么std::array不包含初始化列表构造函数
- C++ 为类模板提供初始值设定项列表构造函数
- 何时使用初始值设定项列表构造函数