我有以下代码 - :
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。
答案 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
的成员函数,例如insert
或erase
。
将item
更改为&item
不会对此有所帮助;如果你这样做,你会得到一个编译时错误,因为该集合的元素是const,所以你不能将reverse
应用于它们。
答案 1 :(得分:4)
这个基于范围的循环可以复制集合中的每个元素:
INSERT INTO table1
SELECT * FROM table2
这就是为什么你可以修改循环中的for ( auto item : s )
而不会触发编译器错误。
如果要修改容器的元素,则需要引用。使用它确实会导致编译器错误,因为无法修改集合的元素:
item
答案 2 :(得分:1)
std :: set中的对象是const,因为它们用作键。所以你不能像这样修改集合中的对象。