我是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()
即可。我知道我可以简单地使用&#34;范围基于&#34;为此,但问题是:为什么统一初始化不适用于迭代器,但对于int i{0};
这样的基本类型是否正常?
答案 0 :(得分:4)
当您使用初始化程序列表作为auto
的初始化程序时,声明的变量将被推导为初始化程序列表。换句话说,iter
被声明为std::initializer_list<vector<int>::iterator>
,而不是您所期望的vector<int>::iterator
。
将其更改为auto iter = t.begin()
是继续进行的最佳方式。
答案 1 :(得分:3)
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语句而初始化器是braced-init-list(8.5.4),则程序格式错误。 否则,通过用新的发明类型模板参数U替换auto的出现来获取P,或者如果初始化器是braced-init-list,则使用std :: initializer_-替换列表即可。使用函数调用(14.8.2.1)中的模板参数推导规则来推导U的值,其中P是函数模板参数类型,初始化器是相应的参数。如果扣除失败,则声明格式不正确。否则,为变量或返回类型推导出的类型是 通过将推导的U代入P中获得。
(强调我的)。
Scott Meyer最近就此问题提出了a talk。我建议观看视频。