swap-ranges and rbegin/rend question

I don't get why I get a compiler error.
Can someone explain and correct me what I have done with the swap-ranges?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <deque>
#include <list>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
using namespace std;
void myfunction(int i){
    cout << ""<< i;
}

int main(){
    int t[] = { 10,5,9,6,2,4,7,8,3,1};
    set<int>s1(t,t+10);
    vector<int>v1(s1.rbegin(),s1.rend());
    swap_ranges(s1.begin(),s1.end(),v1.begin());
    for_each(v1.begin(),v1.end(),myfunction);
    for_each(s1.begin(),s1.end(),myfunction);
    return 0;

}
You are not allowed to modify the elements in a std::set, only add and remove.
You are not allowed to modify the elements in a std::set, only add and remove.

In other words, iterators of std::set cannot be used to change the elements they're pointing to, which is what you try to do when using std::swap_ranges().

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <set>

int main()
{
    std::set<int> si;

    si.insert(4);
    std::cout << *si.begin() << std::endl; // fine
    *si.begin() = 5; // compilation error
}


The reason for this is that std::set is usually implemented as a binary tree of some sort. When you insert and erase elements, the structure of the tree changes to keep it valid.

If you could simply change the values in the tree nodes without also appropriately changing the structure of the tree, the tree may become invalid.
As long as order is not disturbed as defined by the Compare template parameter it is fine to change the state of set elements, however you must be careful - the only code that should be allowed to change the state of elements in a set should be the same code that defines the Compare template parameter.
Topic archived. No new replies allowed.