std::for_each在std::集,c++ 11

时间:2022-12-13 18:02:49

Iterating over a vector works:

迭代向量的工作:

std::vector<int> collection = {2, 3, 4, 5435345, 2};
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;});

but not over a set (compile error):

但不超过一组(编译错误):

std::set<int> collection = {2, 3, 4, 5435345, 2};
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;});

Why can't I iterate over a std::set with std::for_each?

为什么我不能迭代一个std::设置为std::for_each?

Bonus question: Also, I would like to change the int& in the lambda's argument to auto&, why can't this be automatically deduced?

附加问题:另外,我想把lambda参数中的int&更改为auto&,为什么不能自动推断出来呢?

4 个解决方案

#1


19  

std::set<T>::value_type is T const, not T; consequently, the argument to your lambda must be a value type (i.e., copy) or int const& (and technically, or int const volatile&), not int&. I.e., this works:

设置 : value_type is T const, not T;因此,lambda的参数必须是一个值类型(例如。,复制)或int const&(技术上,或int const挥发物&),而不是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; }
);

Bonus question: Also, I would like to change the int& in the lambda's argument to auto&, why can't this be automatically deduced?

附加问题:另外,我想把lambda参数中的int&更改为auto&,为什么不能自动推断出来呢?

Because the standard says it can't; historically, I believe this was due to overly-complicated interactions between lambdas and concepts (before concepts were removed from the draft). However, I hear rumors that the first defect reports to the new (C++11) standard will address exactly this, so it's possible that you'll see support for this added to your compiler of choice within the next year or two. EDIT: Oh, look, C++14 now has polymorphic lambdas...

因为标准说它不能;从历史上看,我认为这是由于lambdas和概念之间过于复杂的交互(在概念从草案中删除之前)。但是,我听说有传言说,第一个缺陷报告将会针对这个新的(c++ 11)标准来解决这个问题,所以在接下来的一两年里,您可能会看到对这个添加到编译器的支持。编辑:哦,看,c++ 14现在有多态的lambdas……

#2


3  

Concerning the bonus question: An "auto" function argument isn't specific to lambdas. You might as well ask why we don't allow all functions to be declared as f(auto x, auto y). But that just means that you essentially want to replace all functions by function templates. That was considered not to work well with the existing C++ language and the type system in particular. If you want a function template, there's already an existing syntax and mechanism, and declaring "auto" arguments is not the way to go.

关于附加问题:“auto”函数参数不是特定于lambdas的。你也可以问为什么我们不允许所有的函数都被声明为f(auto x, auto y),但这只是意味着你想用函数模板替换所有的函数。这被认为不能很好地与现有的c++语言和类型系统一起工作。如果您想要一个函数模板,已经有一个现有的语法和机制,声明“auto”参数不是正确的方法。

#3


1  

A dereferenced set<int> iterator is a const int&. So you can't pass it as an int& parameter without the const. Try either plain (int i) or (const int& i).

取消引用集 迭代器是一个const int&。因此,如果没有const,就不能将其作为int&parameter传递。试试普通的(int i)或(const int&i)。

And that's really not one of the places you're allowed to use auto. I think auto only works in a declaration with initializer or as a placeholder for a trailing return type.

这并不是允许你使用汽车的地方。我认为auto只在带有初始化器的声明中工作,或者作为跟踪返回类型的占位符。

#4


0  

You should be able to iterate over a set. However, note that since the element in a set its also its key, it cannot be modified. Change your code to take a const reference, and use cbegin/cend instead, regardless of whether is a set or not when you are not going to modify the elements.

您应该能够对集合进行迭代。但是,请注意,由于集合中的元素也是它的键,所以不能对它进行修改。更改代码以获取const引用,并使用cbegin/,无论您不修改元素时是否设置。

#1


19  

std::set<T>::value_type is T const, not T; consequently, the argument to your lambda must be a value type (i.e., copy) or int const& (and technically, or int const volatile&), not int&. I.e., this works:

设置 : value_type is T const, not T;因此,lambda的参数必须是一个值类型(例如。,复制)或int const&(技术上,或int const挥发物&),而不是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; }
);

Bonus question: Also, I would like to change the int& in the lambda's argument to auto&, why can't this be automatically deduced?

附加问题:另外,我想把lambda参数中的int&更改为auto&,为什么不能自动推断出来呢?

Because the standard says it can't; historically, I believe this was due to overly-complicated interactions between lambdas and concepts (before concepts were removed from the draft). However, I hear rumors that the first defect reports to the new (C++11) standard will address exactly this, so it's possible that you'll see support for this added to your compiler of choice within the next year or two. EDIT: Oh, look, C++14 now has polymorphic lambdas...

因为标准说它不能;从历史上看,我认为这是由于lambdas和概念之间过于复杂的交互(在概念从草案中删除之前)。但是,我听说有传言说,第一个缺陷报告将会针对这个新的(c++ 11)标准来解决这个问题,所以在接下来的一两年里,您可能会看到对这个添加到编译器的支持。编辑:哦,看,c++ 14现在有多态的lambdas……

#2


3  

Concerning the bonus question: An "auto" function argument isn't specific to lambdas. You might as well ask why we don't allow all functions to be declared as f(auto x, auto y). But that just means that you essentially want to replace all functions by function templates. That was considered not to work well with the existing C++ language and the type system in particular. If you want a function template, there's already an existing syntax and mechanism, and declaring "auto" arguments is not the way to go.

关于附加问题:“auto”函数参数不是特定于lambdas的。你也可以问为什么我们不允许所有的函数都被声明为f(auto x, auto y),但这只是意味着你想用函数模板替换所有的函数。这被认为不能很好地与现有的c++语言和类型系统一起工作。如果您想要一个函数模板,已经有一个现有的语法和机制,声明“auto”参数不是正确的方法。

#3


1  

A dereferenced set<int> iterator is a const int&. So you can't pass it as an int& parameter without the const. Try either plain (int i) or (const int& i).

取消引用集 迭代器是一个const int&。因此,如果没有const,就不能将其作为int&parameter传递。试试普通的(int i)或(const int&i)。

And that's really not one of the places you're allowed to use auto. I think auto only works in a declaration with initializer or as a placeholder for a trailing return type.

这并不是允许你使用汽车的地方。我认为auto只在带有初始化器的声明中工作,或者作为跟踪返回类型的占位符。

#4


0  

You should be able to iterate over a set. However, note that since the element in a set its also its key, it cannot be modified. Change your code to take a const reference, and use cbegin/cend instead, regardless of whether is a set or not when you are not going to modify the elements.

您应该能够对集合进行迭代。但是,请注意,由于集合中的元素也是它的键,所以不能对它进行修改。更改代码以获取const引用,并使用cbegin/,无论您不修改元素时是否设置。