问题
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.
回答1:
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.
回答2:
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
回答3:
Objects in an std::set are const, since they are used as keys. So you cannot modify objects in set like this .
来源:https://stackoverflow.com/questions/31153825/modifying-elements-in-stdset