Std :: for_each via std :: set, C ++ 11

Vector iteration 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 the set (compilation 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 std::for_each over std::set with std::for_each ?

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

+7
source share
4 answers

std::set<T>::value_type T const , not T ; therefore, your lambda argument must be a value type (i.e. a copy) or int const& (and technically, or int const volatile& ), not int& . Ie 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 argument to auto& , why can't this be automatically output?

Because the standard says it cannot; Historically, I believe this was due to the overly complex interactions between lambdas and concepts (before concepts were removed from the draft). However, I hear rumors that the first defect reporting to the new (C ++ 11) standard will be addressed that way, so you can see support for this choice added to your compiler over the next year or two. EDIT : Oh look, C ++ 14 now has polymorphic lambda ...

+19
source

Regarding the bonus question: the argument to the "auto" function is not specific to lambdas. You may also ask why we do not allow all functions to be declared as f(auto x, auto y) . But that means you really want to replace all functions with function templates. It was believed that this did not work very well with the existing C ++ language and the type system in particular. If you need a function template, the existing syntax and mechanism already exists, and declaring an β€œauto” argument is not an option.

+3
source

The dereferenced set<int> iterator is const int& . Therefore, you cannot pass it as an int& parameter without const . Try either simple (int i) or (const int& i) .

And this is really not one of the places where you are allowed to use auto . I think auto only works in declarations with an initializer or as a placeholder for the return type.

+1
source

You should be able to iterate through the set. However, note that since the item in the set is also its key, it cannot be changed. Modify your code to take a const reference, and use cbegin/cend instead, whether it is a collection or not when you are not going to change the elements.

0
source

All Articles