不同时期STL的注意事项
VS2010或大部分gcc版本以前使用 STL对比最新STL版本的map
(部分gcc使用了新的STL,绝大部分使用的还以前的STL);
又发现一个挺有趣的事
class Data
{
public:
Data(void)
{
cout << "Constructor" << endl;
}
Data(const Data& other)
{
cout << "Copy Constructor" << endl;
}
Data& operator=(const Data& other)
{
cout << "Assignment operator" << endl;
return *this;
}
~Data(void)
{
cout << "Destructor" << endl;
}
};
int main()
{
{map<int, Data> c;
Data d = Data();
c[1] = d;}
return 0;
}
按照分析应该是输出什么呢
理论上来说应该是在main函数的第二行一次构造,在第三行应该是map先构造准备好空间然后接受d的赋值最后三次析构
这在vs2013和最新的STL实现中的输出是一致的,在我机器mingw里面的SGISTL实现输出也是这样:
但在同样不算很旧的vs2010中输出是这样的,在某网络上最新的gcc 4.8也是这样的:
vs2010也不能说老吧,大多数vs开发不会超过这个版本吧,这是怎么回事呢
我们看一下这一片输出的罪魁祸首吧
iterator __i = lower_bound(__k);
// __i->first is greater than or equivalent to __k.
if (__i == end() || key_comp()(__k, (*__i).first))
__i = insert(__i, value_type(__k, mapped_type()));
return (*__i).second;
呵呵,这是什么?
如果你如果使用的是operator[ ],那么他先会找到该处迭代器,如果没找到,那好就构造一个默认值的pair,然后把pair在拷贝到map所在红黑树的树节点中,拷贝完了,再然后才去检查你到底要插入的是什么值。
如果,没有版本间测试或是测试中没有考虑为什么这个还真不好发现呢。
这个告诉了我们什么?意义何在:
vs2010编程时如果是插值尽量使用insert,而vs2013 则没这个限制,呵呵是不是很蛋疼,SGI STL一样适用,前后效率还差不少。