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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With