修改std :: set中的元素

Anm*_*ggi 2 c++ gcc stl std stdset

我有以下代码 - :

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

输出 - :

abab
asas

abab
asas
Run Code Online (Sandbox Code Playgroud)

reverse()函数根本没有修改集合的元素.
我怀疑集合中的元素根本无法修改.但是,如果是这种情况,为什么编译器本身不会出错呢?

-std=c++14在Windows 7上使用带有标志的TDM-GCC 4.9.2 .

Bil*_*eal 7

一个元素std::setconst.如果要改变元素,则需要执行插入和移除以将容器置于所需的状态.

在您的代码示例中:

for (auto item : s)
Run Code Online (Sandbox Code Playgroud)

被翻译成如下:

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

循环归纳变量item是元素的副本set,而不是对实际元素的引用set.结果,set没有改变.要更改集合,您需要调用set例如insert或的成员函数erase.

改变item&item这里无济于事; 如果你这样做,你会得到编译时错误,因为集合的元素是const,所以你不能应用reverse它们.


jua*_*nza 5

这个基于范围的循环会复制集合中的每个元素:

for ( auto item : s )
Run Code Online (Sandbox Code Playgroud)

这就是为什么您可以item在循环中进行修改而不会触发编译器错误。

如果您想修改容器的元素,则需要一个引用。使用它确实会导致编译器错误,因为集合的元素无法修改:

for ( auto& item : s )
{
  // s is a set. You cannot modify item
Run Code Online (Sandbox Code Playgroud)