Range based loop for a set of a struct type

Using C++11 over here. Let's say I have a struct like this:
1
2
3
4
struct Something{
    string name;
    int code;
};


And a set of Something type:
1
2
3
4
set<Something> myset;
myset.insert({"aaa",123,});
myset.insert({"bbb",321});
myset.insert({"ccc",213});


Why can't I do this?
1
2
3
4
for (auto sth : myset){
       cout << sth.name;
       cout << sth.code;
}


Is it just not possible or I'm missing something else?


Along the same lines... why can't I modify an element using
1
2
3
for (auto &sth : myset){
       sth=[some value];
}

I know I can do this with vectors and maps though...
Last edited on
Why can't I do this?

What kind of error messages are you getting?

Along the same lines... why can't I modify an element using

Again what kind of errors are you getting?


Last edited on
For the first loop:
error: no match for 'operator<' (operand types are 'const Something' and 'const Something')

(I tried for (auto const sth : myset) and didn't work either).


Second one:
error: passing 'const Something' as 'this' argument of 'Something& Something::operator=(Something&&)' discards qualifiers [-fpermissive]
error: no match for 'operator<' (operand types are 'const Something' and 'const Something')


So did you create that operator< overload? You need a comparison operator to use your class with a std::set.

Do you realize that with a std::set operator= is copying the the rhs object to the lhs object? It is not "adding" an additional element to the set. Did you look up the documentation for std::set? How is operator= and operator[] implemented for this class?

I understand, I was just reducing the lines of code as much as possible to just illustrate the question.
I'm not overloading the operator because I didn't need to with vectors. Why is it different with sets?

With a vector I can do:
1
2
3
4
for (auto sth : myvector){
       cout << sth.name;
       cout << sth.code;
}


And I can also do:
1
2
3
4
for (auto &sth : myvector){
       if (sth.name=="some name")
           sth.code=0;
}


However, this is not possible with set or unordered_set. Why is that?
So, two questions:
Is there a way I can iterate over structs in a set using a range-based for?
What's different with set or unordered_set that doesn't allow me to take a copy by reference when I use a range-based for?
Last edited on
Why is it different with sets?

A set is "sorted" by a condition, that is why you need the operator< to determine how to sort the Something. Until you implement the operator< you will continue to have problems.

With a vector I can do:

You should be able to iterate over a set as well. However once an element is placed within a set it can not be changed, it is const.

See this link: http://www.cplusplus.com/reference/set/set/

And from that link:
In a set, the value of an element also identifies it (the value is itself the key, of type T), and each value must be unique. The value of the elements in a set cannot be modified once in the container (the elements are always const), but they can be inserted or removed from the container.





Woo, I completely forgot they can't be modified! Thanks!!


Topic archived. No new replies allowed.