考虑下面的代码:初始化std :: map中的原始类型的值是否已初始化?
map<int,int> m;
for(int i=0;i<10000;++i) m[i]++;
for(int i=0;i<10000;++i) printf("%d",m[i]);
我以为打印出来的值将是不确定的,因为原始类型没有默认构造函数,但在这里我得到了我每次测试时间1秒10000。
为什么初始化?
考虑下面的代码:初始化std :: map中的原始类型的值是否已初始化?
map<int,int> m;
for(int i=0;i<10000;++i) m[i]++;
for(int i=0;i<10000;++i) printf("%d",m[i]);
我以为打印出来的值将是不确定的,因为原始类型没有默认构造函数,但在这里我得到了我每次测试时间1秒10000。
为什么初始化?
当调用operator[]
并且键缺失时,使用表达式mapped_type()
(它是类类型的默认构造函数)和整型类型的零初始化来初始化该值。
实际上,你确定这是答案吗?在[map :: operator []](http://www.cplusplus.com/reference/map/map/operator [] /)上,它表示:“ 对此函数的调用相当于: (*( this-> insert(make_pair(k,mapped_type()))。first))。second“这表明pair的值初始化并不重要 –
您确定使用cplusplus.com吗? – LogicStuff
克里斯有一点。 'pair'的默认构造函数显然没有被使用 - 这个对中的第一个成员是在这里从0到10000的整数索引'i'。如果默认的ctor已经被使用,那么'first'成员将为零,并且由于地图不能包含重复的键,所以只有一个映射条目。由于我们知道已经打印了10000个,我们知道默认对ctor没有被使用。 – MSalters
见https://www.sgi.com/tech/stl/stl_map.h
_Tp& operator[](const key_type& __k) {
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, _Tp()));
return (*__i).second;
}
在你的榜样,_TP是int
,而int()
是0
#include <iostream>
using namespace std;
int main() {
int x = int();
cout << x << endl;
return 0;
}
另外:
感谢@MSalters谁讲述上面的代码是SGI而不是std :: map,但我认为它有些像...
这实际上是STL'map'类,而不是'std :: map'。后者受到前者的启发,但存在细微的差异。这个问题是关于一分钟的细节。但是,是的,因为它发生在这里没有分歧。 – MSalters
你是对的,有很多STL版本,SGI,STLPort,微软版本等。 – kaitian521
如果微软有一个STL派生的库,那是20年前。 (也许VC4,不记得细节)。他们绝对转而使用C++ 98标准库实现VC6实现Dinkumware。 – MSalters
std::map::operator[]如果不存在,则插入新值。如果执行插入操作,映射值将由默认构造函数初始化为类类型,否则将被初始化为zero-initialized。
在C++ 14标准,部分[map.access]
文本是:
T& operator[](const key_type& x);
- 效果:如果没有键相当于
x
在地图,插入value_type(x, T())
到地图。
所以,也由约瑟夫·加尔文的回答说,表达mapped_type()
的结果是什么插入。这种初始化称为value-initialization。
对于类的类型,值初始化的含义并不像其他答案中那样简单。它取决于类类型具有的构造函数类型,以及该类是否为聚合,正如cppreference链接所解释的。
对于int
就像在这个问题中那样,值初始化意味着int
被设置为0
。
0是未定义变量的合法值。 – 2016-07-24 09:21:46