迭代向量的工作原理:
std::vector<int> collection = {2, 3, 4, 5435345, 2};
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;});
但不是一组(编译错误):
std::set<int> collection = {2, 3, 4, 5435345, 2};
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;});
为什么我无法使用std::set
迭代std::for_each
?
奖金问题:
另外,我想将lambda的参数中的int&
更改为auto&
,为什么不能自动推断出这一点?
答案 0 :(得分:19)
std::set<T>::value_type
为T const
,而不是T
;因此,lambda的参数必须是值类型(即复制)或int const&
(技术上或int const volatile&
),而不是int&
。即,这有效:
std::set<int> collection{2, 3, 4, 5435345, 2};
std::for_each(
collection.begin(),
collection.end(),
[](int const& i) { std::cout << i << std::endl; }
);
奖金问题:另外,我想将lambda参数中的
int&
更改为auto&
,为什么不能自动推断出这一点?
因为标准说它不能;从历史上看,我认为这是由于lambda和概念之间过于复杂的相互作用(在概念从草案中删除之前)。 但是,我听说有传言说新的(C ++ 11)标准的第一个缺陷报告将完全解决这个问题,所以你可能会在明年看到对你选择的编译器的支持。两个。 编辑:哦,看,C ++ 14现在有多态lambdas ......
答案 1 :(得分:3)
关于奖金问题:“自动”功能参数不是特定于lambdas。您也可以问为什么我们不允许将所有函数声明为f(auto x, auto y)
。但这只是意味着您基本上想要通过功能模板替换所有功能。这被认为与现有的C ++语言和特别是类型系统不兼容。如果你想要一个函数模板,那么已经有了一个现有的语法和机制,并且声明“自动”参数不是可行的方法。
答案 2 :(得分:1)
解除引用的set<int>
迭代器是const int&
。因此,如果没有int&
,则无法将其作为const
参数传递给您。尝试使用普通(int i)
或(const int& i)
。
这并不是您允许使用auto
的其中一个地方。我认为auto
仅适用于具有初始化程序的声明或作为尾随返回类型的占位符。
答案 3 :(得分:0)
你应该可以迭代一套。但是,请注意,由于集合中的元素也是其关键,因此无法修改。更改您的代码以获取const
引用,并使用cbegin/cend
代替,无论是否是一组,当您不打算修改元素时。