std :: for_each over std :: set,C ++ 11

时间:2011-11-14 22:18:11

标签: c++ stl foreach set c++11

迭代向量的工作原理:

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&,为什么不能自动推断出这一点?

4 个答案:

答案 0 :(得分:19)

std::set<T>::value_typeT 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代替,无论是否是一组,当您不打算修改元素时。