gpt4 book ai didi

c++ - 构造函数采用初始化列表

转载 作者:行者123 更新时间:2023-12-01 14:22:39 26 4
gpt4 key购买 nike

我明白了用花括号统一初始化背后的想法。但是,为什么在具有采用初始化列表的构造函数的类型上使用此语法,调用该特定构造函数,即使参数仅包含在一对大括号中,即

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}};

为此?这有点令人困惑,尤其是当您不知道某个类具有采用初始化列表的构造函数时。

最佳答案

这听起来像是在寻求动力,而不是标准中规定必须这样做的地方。为此,您可以查看 original proposal N1919 for intializer lists作者 Bjarne Stroustrup,C++ 语言的创造者。

他列出了四种初始化对象的方法:

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,也不是引入了初始化列表的提议版本。这回到了 C++98。大括号初始化语法已经有效,但仅适用于 C 风格的结构,即没有用户定义的构造函数。这是 C 的延续,它始终允许以这种方式初始化结构(和数组),并且它总是做同样的事情:逐个元素地初始化。

提案的重点是允许初始化适当的 C++ 对象,如 std::vector<int>与那些 C 风格的结构和数组一样: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++ - 构造函数采用初始化列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62301746/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com