7

可以构造一个带有迭代器范围的向量,如下所示:

std::vector<std::string> vec(std::istream_iterator<std::string>{std::cin},
                             std::istream_iterator<std::string>{});

但我也可以使用 C++11 统一初始化语法(注意括号)编译和运行代码,如下所示:

std::vector<std::string> vec{std::istream_iterator<std::string>{std::cin},
                             std::istream_iterator<std::string>{}};

这里到底发生了什么?

我知道采用初始化列表的构造函数优先于其他形式的构造。编译器不应该解析为构造函数采用包含 2 个元素的初始化列表std::istream_iterator吗?这应该是一个错误,因为std::istream_iterator不能转换为向量值类型std::string,对吧?

4

1 回答 1

6

从 §13.3.2/1 ([over.match.list])

当非聚合类类型的对象T被列表初始化(8.5.4)时,重载决议分两个阶段选择构造函数:

— 最初,候选函数是类的初始化列表构造函数(8.5.4),T参数列表由初始化列表作为单个参数组成。

— 如果没有找到可行的初始化列表构造函数,则再次执行重载决议,其中候选函数是类的所有构造函数,T参数列表由初始化列表的元素组成。

在您的情况下,初始化列表构造函数被认为是不可行的(因为std::istream_iterator<std::string>不能转换为std::string),并且第二个条件适用。这导致构造函数需要选择 2 个迭代器。

于 2013-07-31T20:14:12.033 回答