修改std::set中的元素

Modifying elements in std::set

本文关键字:元素 set std 修改      更新时间:2023-10-16

我有以下代码-:

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";
    }
}

输出-:

abab
asas
abab
asas

reverse()函数根本不会修改集合的元素
我怀疑集合中的元素根本不能被修改。但是,如果是这样的话,为什么编译器自己不首先给出错误呢?

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

std::set的元素是const。如果你想改变元素,你需要进行插入和删除,以使容器处于你想要的状态。

在您的代码示例中:

for (auto item : s)

被翻译成类似于:

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

循环诱导变量itemset中元素的副本,而不是对set中实际元素的引用。结果,set没有改变。要更改集合,您需要调用set的成员函数,例如inserterase

item更改为&item在这里没有帮助;如果你这样做,你会得到一个编译时错误,因为集合的元素是常量,所以你不能对它们应用reverse

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

for ( auto item : s )

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

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

for ( auto& item : s )
{
  // s is a set. You cannot modify item
std::集中的对象是常量,因为它们被用作键。所以不能像这样修改集合中的对象。