c++ - 为什么 'std::vector<int> b{2};' 创建一个 1 元素 vector ,而不是 2 元素 vector ?

标签 c++ c++11 initializer-list uniform-initialization

过去几天我一直在玩 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 通过列表初始化进行初始化,此行为是有意的

When objects of non-aggregate class type T are list-initialized (8.5.4), overload resolution selects the constructor in two phases:

— Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class T and the argument list consists of the initializer list as a single argument.

— If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the class T and the argument list consists of the elements of the initializer list.

至于“统一初始化的全部目的”……“统一初始化”是一个营销术语,并不是一个很好的描述。该标准具有所有常见的初始化形式加上列表初始化,但没有“统一初始化”。列表初始化并不是初始化的终极形式,它只是实用工具带中的另一个工具。

关于c++ - 为什么 'std::vector<int> b{2};' 创建一个 1 元素 vector ,而不是 2 元素 vector ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9723164/

相关文章:

c++ - 使用 std::initializer_list 构造函数而不产生歧义?

c++ - 编译器如何选择正确的函数?

c++ - std::memory_order_relaxed 是否足以检查 "Availability"?

c++ - std::vector 和 std::array 初始化列表之间的区别

C++ union/结构位域实现和可移植性

c++11 - 如何在 Qt Creator 2.8.0 的通用项目中启用 C++11 支持?

c++11 - 在 C++11 中为 STL 容器分配一个支撑初始化列表

c++ - 将 double 组输出到硬盘驱动器上的文件

c++ - Apache Thrift 未定义对生成代码中 vtable 的引用

c++ - std::string::substr 成员函数的复杂度是多少?