Search code examples
c++gccstlstdstdset

Modifying elements in std::set


I have the following code -:

int main()
{
    set<string> s;
    s.insert( "asas" );
    s.insert( "abab" );

    for ( auto item : s )
    {
        cout << item << "\n";
        reverse( item.begin(), item.end() );
    }

    cout << "\n";

    for ( auto item : s )
    {
        cout << item << "\n";
    }
}

Output -:

abab
asas

abab
asas

The elements of the set are not being modified at all by the reverse() function.
I suspect that the elements inside a set cannot be modified at all. But, if this is the case, why doesn't the compiler give an error in the first place itself ?

I am using TDM-GCC 4.9.2 with -std=c++14 flag on Windows 7.


Solution

  • Elements of a std::set are const. If you want to mutate the elements you need to do insertions and removals to put the container in the state you want.

    In your code example:

    for (auto item : s)
    

    gets translated into something like:

    for (auto iter = s.begin(); iter != s.end(); ++iter)
    {
        auto item = *iter; // Copy!
        // loop body
    }
    

    The loop induction variable item is a copy of the element from the set, not a reference to the actual element in the set. As a result, the set is not changed. To change a set you need to call a member function of set, e.g. insert or erase.

    Changing item to &item won't help here; if you do this you'll get a compile-time error because the elements of the set are const, so you can't apply reverse to them.