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:
设置
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 toauto&
, 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)
.
取消引用集
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:
设置
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 toauto&
, 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)
.
取消引用集
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/,无论您不修改元素时是否设置。