简体   繁体   English

迭代器的统一初始化

[英]Uniform initialization of iterators

I am very new to C++11 and there is a problem with iterators and uniform initialization, which I do not understand. 我是C ++ 11的新手,迭代器和统一初始化存在问题,我不明白。

Consider the following example, which does not compile: 请考虑以下示例,该示例无法编译:

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

In line 6 a vector is initialized using uniform initialization. 在第6行中,使用统一初始化初始化向量。 In line 7 I try to do the same with an iterator. 在第7行中,我尝试使用迭代器执行相同的操作。 It does not work. 这是行不通的。 Changing line 7 to auto iter = t.begin() is ok. 将第7行更改为auto iter = t.begin() I know I could simply use "range based for" for this, but the question is: Why does uniform initialization not work with iterators but is fine with basic types, like int i{0}; 我知道我可以简单地使用“基于范围”,但问题是:为什么统一初始化不适用于迭代器,但对于基本类型(如int i{0}; ?

When you use an initializer-list as the initializer with auto , the variable declared is deduced as an initializer list. 当您使用初始化列表作为auto的初始化程序时,声明的变量将被推导为初始化列表。 In other words, iter is declared as std::initializer_list<vector<int>::iterator> , and not vector<int>::iterator as you might expect. 换句话说, iter被声明为std::initializer_list<vector<int>::iterator> ,而不是你vector<int>::iterator

Changing it to auto iter = t.begin() is the best way to proceed. 将其更改为auto iter = t.begin()是继续进行的最佳方式。

C++11 has a special rule for auto and braced initialization which is inferred to std::initializer_list . C ++ 11有一个特殊的auto和支撑初始化规则,它被推断为std::initializer_list In your case your choices are one of the following: 在您的情况下,您的选择是以下之一:

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

The behavior is described at: 行为描述于:

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

Let T be the declared type of the variable or return type of the function. 令T为函数的变量或返回类型的声明类型 If the placeholder is the auto type-specifier, the deduced type is determined using the rules for template argument deduction. 如果占位符是自动类型说明符,则使用模板参数推导的规则确定推导的类型。 If the deduction is for a return statement and the initializer is a braced-init-list (8.5.4), the program is ill-formed. 如果扣除是针对return语句而初始化器是braced-init-list(8.5.4),则程序格式错误。 Otherwise, obtain P from T by replacing the occurrences of auto with either a new invented type template parameter U or, if the initializer is a braced-init-list, with std::initializer_- list . 否则,通过用新发明的类型模板参数U 替换auto的出现来获得P,或者如果初始化器是braced-init-list,则用std :: initializer_- list替换 Deduce a value for U using the rules of template argument deduction from a function call (14.8.2.1), where P is a function template parameter type and the initializer is the corresponding argument. 使用函数调用(14.8.2.1)中的模板参数推导规则来推导U的值,其中P是函数模板参数类型,初始化器是相应的参数。 If the deduction fails, the declaration is ill-formed. 如果扣除失败,则声明格式不正确。 Otherwise, the type deduced for the variable or return type is obtained by substituting the deduced U into P. 否则,通过将推导的U代入P来获得为变量或返回类型推导出的类型。

(emphasis mine). (强调我的)。

Scott Meyer has recently presented a talk about this very problem. Scott Meyer最近提出了一个关于这个问题的讨论。 I'd recommend watching the video. 我建议观看视频。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM