侯捷大师在 STL 源码剖析中说道,set 的迭代器的值是不可改变的,这个本来很好理解,但是我神奇的在 visual studio 2005 上发现,神奇的事情总是会发生
#include <stdio.h> #include <map> #include <string> #include <set> int main() { std::set<int> setInt; setInt.insert(1); setInt.insert(2); for (std::set<int>::iterator it = setInt.begin(); it != setInt.end(); it++) { printf("%d\n", *it); } { std::set<int>::iterator it = setInt.begin(); *it = 4; it++; *it = 3; } for (std::set<int>::iterator it = setInt.begin(); it != setInt.end(); it++) { printf("%d\n", *it); } return 0; }
居然顺利的编译通过,而且可以跑,看看输出
1 2 4 3 请按任意键继续. . .
照理说,set 的底下是红黑树的话,这里应该是会违反红黑树的大小排序原则的。。
甚至改成这样
#include <stdio.h> #include <map> #include <string> #include <set> int main() { std::set<int> setInt; setInt.insert(1); setInt.insert(2); for (std::set<int>::iterator it = setInt.begin(); it != setInt.end(); it++) { printf("%d\n", *it); } { std::set<int>::iterator it = setInt.begin(); *it = 4; it++; *it = 4; } for (std::set<int>::iterator it = setInt.begin(); it != setInt.end(); it++) { printf("%d\n", *it); } return 0; }
也可以。。好吧,set 的原则也被破坏了。。
来看 gcc 4.1 的编译输出
StlContainerTest.cpp:25:2: warning: no newline at end of file StlContainerTest.cpp: In function 'int main()': StlContainerTest.cpp:16: error: assignment of read-only location StlContainerTest.cpp:18: error: assignment of read-only location
这个才是符合预期的嘛,M$ 这样会坑死人啊。。