【问题标题】:Construct container with initializer list of iterators使用迭代器的初始化列表构造容器
【发布时间】:2013-08-01 12:54:39
【问题描述】:

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

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

这里到底发生了什么?

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

【问题讨论】:

  • @P0W 是的! :) 我已经多次使用这种语法,但它让我想知道你何时将其描述为使用 C++11 初始化列表而不是简单的统一初始化括号。

标签: c++ c++11 iterator uniform-initialization


【解决方案1】:

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

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

——最初,候选函数是初始化列表 T 类的构造函数(8.5.4)和参数列表包括 初始化器列表作为单个参数。

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

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

【讨论】:

  • 还有解释。谢谢! :)
猜你喜欢
  • 2017-01-03
  • 1970-01-01
  • 1970-01-01
  • 2013-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多