【问题标题】:Uniform initialization of iterators迭代器的统一初始化
【发布时间】:2014-06-15 20:25:38
【问题描述】:

我对 C++11 很陌生,迭代器和统一初始化有问题,我不明白。

考虑下面的例子,它不能编译:

#include <iostream>
#include <vector>

int main() {

    std::vector<int> t{1, 2, 3, 4, 5};
    auto iter{t.begin()};                   

    for (; iter != t.end(); ++iter) {
        std::cout << *iter;
    }

    return 0;
}

在第 6 行中,使用统一初始化对向量进行了初始化。在第 7 行中,我尝试对迭代器执行相同的操作。这没用。将第 7 行更改为 auto iter = t.begin() 即可。我知道我可以为此简单地使用“基于范围”,但问题是:为什么统一初始化不适用于迭代器,但适用于基本类型,例如 int i{0};?

【问题讨论】:

  • 顺便说一句 auto iter{t.begin()}; 很好,是后来导致问题的原因

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


【解决方案1】:

当您使用初始化器列表作为带有auto 的初始化器时,声明的变量被推导出为初始化器列表。换句话说,iter 被声明为 std::initializer_list&lt;vector&lt;int&gt;::iterator&gt;,而不是您所期望的 vector&lt;int&gt;::iterator。

将其更改为 auto iter = t.begin() 是最好的方法。

【讨论】:

  • 请注意,这可能会更改 in the future。建议的(破坏性)更改是 direct-list-initialization 永远不会推断出initializer_list。
【解决方案2】:

C++11 有一个针对auto 的特殊规则和推断为std::initializer_list 的大括号初始化。在您的情况下,您的选择是以下之一:

auto iter(t.begin());
auto iter = t.begin();

行为描述在:

§7.1.6.4/7 auto 说明符 [dcl.spec.auto]

令 T 为变量的声明类型或函数的返回类型。如果占位符是自动类型说明符,则使用模板参数推导规则确定推导类型。如果推导是针对 return 语句并且初始化程序是一个花括号初始化列表(8.5.4),则程序是非良构的。 否则,通过将出现的 auto 替换为新发明的类型模板参数 U 或 如果初始化器是花括号初始化器列表,使用 std::initializer_- 从 T 中获取 P列表。使用从函数调用 (14.8.2.1) 的模板参数推导规则推导出 U 的值,其中 P 是函数模板参数类型,初始化程序是相应的参数。如果扣除失败,则声明格式错误。否则,为变量或返回类型推导的类型是 将推导出的U代入P中得到。

(强调我的)。

Scott Meyer 最近向a talk 介绍了这个问题。我建议观看视频。

【讨论】:

    猜你喜欢
    • 2010-11-18
    • 1970-01-01
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    • 2012-10-14
    相关资源
    最近更新 更多