为什么'std::vector<int> b{2};'创建 1 元素向量,而不是 2 元素向量?
Why does 'std::vector<int> b{2};' create a 1-element vector, and not a 2-element one?
过去几天我一直在玩C++11,我发现了一些奇怪的东西。
如果我想统一初始化一个int:
int a{5};
但如果我对std::vector:做同样的事情
std::vector<int> b{2};
不构造一个双元素数组,而是构造一个包含一个值为2的元素的数组。似乎要获得这种效果,需要更明确地说明:
std::vector<int> c{{2}};
std::vector<int> d = {2};
但与b的声明不同——这似乎不一致。我看过其他一些同样效果的东西。我想问的是,这种行为是在最终的C++11标准中,还是只是在早期实现的草案中?如果是这样的话,为什么标准委员会会将这种行为包括在内?它似乎违背了统一初始化的全部目的,因为必须记住哪些类具有初始值设定项列表构造函数,并对这些类使用旧的()语法而不是{}。或者完全放弃统一初始化。
这似乎是一个很大的"明白"。但它可能有一些我不知道的好处。
编辑:此代码:
#include <iostream>
#include <vector>
int main() {
std::vector<int> a{2};
for (auto x: a) {
std::cout << x << std::endl;
}
return 0;
}
在gcc 4.6.2 上输出"2"
是的,根据§13.3.1.7通过列表初始化进行初始化,此行为是有意的
当非聚合类类型T的对象被列表初始化时(8.5.4),过载解析分两个阶段选择构造函数:
--最初,候选函数是初始值设定项列表类
T
的构造函数(8.5.4),参数列表由初始值设定项列表作为单个参数。--如果不可行找到初始值设定项列表构造函数,重载解析为再次执行,其中候选函数为类
T
的构造函数和参数列表由初始值设定项列表的元素。
至于"统一初始化的全部目的"。。。"统一初始化"是一个市场术语,不是一个很好的描述。该标准具有所有常见的初始化形式加上列表初始化,但没有"统一初始化"。列表初始化并不意味着初始化的最终形式,它只是实用工具带中的另一个工具。
统一初始化并不意味着你所认为的那样。添加它是为了使C++中的类型之间的初始化更加统一。理由是:
typedef struct dog_ {
float height;
int weight;
} dog;
int main() {
dog Spot = { 25.6, 45};
dog Data[3] = { Spot, {6.5, 7} };
std::array<dog, 2> data = { { Spot, {6.5, 7} } }; //only in C++ obviously
return 0;
}
这是有效的C和C++代码,已经存在了很多年。这真的很方便,但你必须记住,这只适用于POD类型。长期以来,人们一直抱怨没有办法实现std::vector<int> data = { 3, 7, 4, 1, 8};
,但有些类(std::array
)以奇怪的方式编写,允许初始化器列表构造函数。
因此,对于C++11,委员会这样做是为了让vector和其他很酷的类也能做到这一点。这使得所有类型的构造更加统一,因此我们可以使用{}
通过构造函数进行初始化,也可以从值列表进行初始化。您遇到的问题是,具有std::initializer_list<int>
的构造函数重载是最匹配的,并且将首先被选中。因此,std::vector<int> b{2};
并不意味着调用采用int
的构造函数,而是意味着从int
值的列表中创建vector
。在这种情况下,创建一个包含单个值2
的vector
是完全合理的。要调用不同的构造函数,您必须使用()
语法,这样C++就知道您不想从列表中初始化。
标准规定初始值设定项列表构造函数优先于其他构造函数。这只是不可能用{}
替换()
的一种情况。还有其他一些,例如{}
初始化不允许缩小转换范围。
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- C++:如何循环通过向量中的整数元素
- 如何在C++向量中奇数元素前面加上值-1,我在使用insert函数时遇到了问题
- 不允许在向量中添加更多元素
- 基于范围的 for 循环:迭代使用一个元素扩展的向量
- 使用并行参数向量调用元素向量的成员函数
- C++ 查找字符串中存在的元素向量
- 包含 std::threads 的元素向量
- 避免从单一元素向量转换为基元类型
- 对自定义元素向量进行排序时出现意外(至少对我来说)行为
- 如何为对元素(向量和int)配对创建unique_ptr也是unique_ptr
- 元素向量乘法 C++(代码不起作用)
- 时间和空间复杂性在二叉树的每个级别创建元素向量(NON-BST)
- 遍历结构元素向量
- 犰狳C++中的元素向量或矩阵乘法
- 为什么'std::vector<int> b{2};'创建 1 元素向量,而不是 2 元素向量?
- 可移动元素向量的大小调整是否有效?
- 唯一元素向量的c++模板函数
- 获取索引和元素-向量问题
- 定义一个生成元素向量的函数时,正确的方法是什么?