修改std :: set中的元素

时间:2015-07-01 06:17:29

标签: 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";
    }
}

输出 - :

abab
asas

abab
asas

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

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

3 个答案:

答案 0 :(得分:7)

std::set的元素是const。如果你想改变你需要插入和移除的元素,以便将容器置于你想要的状态。

在您的代码示例中:

for (auto item : s)

被翻译成:

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

循环归纳变量item是来自set的元素的副本,而不是对set中实际元素的引用。因此,set不会更改。要更改集,您需要调用set的成员函数,例如inserterase

item更改为&item不会对此有所帮助;如果你这样做,你会得到一个编译时错误,因为该集合的元素是const,所以你不能将reverse应用于它们。

答案 1 :(得分:4)

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

INSERT INTO table1
SELECT * FROM table2

这就是为什么你可以修改循环中的for ( auto item : s ) 而不会触发编译器错误。

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

item

答案 2 :(得分:1)

std :: set中的对象是const,因为它们用作键。所以你不能像这样修改集合中的对象。