简体   繁体   中英

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.

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. In line 7 I try to do the same with an iterator. It does not work. Changing line 7 to auto iter = t.begin() is ok. 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}; ?

When you use an initializer-list as the initializer with auto , the variable declared is deduced as an initializer list. In other words, iter is declared as std::initializer_list<vector<int>::iterator> , and not vector<int>::iterator as you might expect.

Changing it to auto iter = t.begin() is the best way to proceed.

C++11 has a special rule for auto and braced initialization which is inferred to 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]

Let T be the declared type of the variable or return type of the function. 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. 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 . 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. 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.

(emphasis mine).

Scott Meyer has recently presented a talk about this very problem. I'd recommend watching the video.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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