STL set 的一些实现差异

侯捷大师在 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$ 这样会坑死人啊。。

Leave a Reply

Your email address will not be published. Required fields are marked *