Anmol Singh Jaggi
Anmol Singh Jaggi

Reputation: 8576

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.

Upvotes: 4

Views: 4285

Answers (3)

mystic_coder
mystic_coder

Reputation: 472

Objects in an std::set are const, since they are used as keys. So you cannot modify objects in set like this .

Upvotes: 1

Billy ONeal
Billy ONeal

Reputation: 106530

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.

Upvotes: 14

juanchopanza
juanchopanza

Reputation: 227390

This range based loop makes copies of every element in the set:

for ( auto item : s )

That is why you can modify item in the loop without triggering a compiler error.

If you wanted to modify the elements of a container, you'd need a reference. Using this would indeed result in a compiler error because the elements of a set can't be modified:

for ( auto& item : s )
{
  // s is a set. You cannot modify item

Upvotes: 5

Related Questions