2016-07-24 184 views
10

考虑下面的代码:初始化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。

为什么初始化?

+4

0是未定义变量的合法值。 – 2016-07-24 09:21:46

回答

12

当调用operator[]并且键缺失时,使用表达式mapped_type()(它是类类型的默认构造函数)和整型类型的零初始化来初始化该值。

+2

实际上,你确定这是答案吗?在[map :: operator []](http://www.cplusplus.com/reference/map/map/operator [] /)上,它表示:“ 对此函数的调用相当于: (*( this-> insert(make_pair(k,mapped_type()))。first))。second“这表明pair的值初始化并不重要 –

+1

您确定使用cplusplus.com吗? – LogicStuff

+1

克里斯有一点。 'pair'的默认构造函数显然没有被使用 - 这个对中的第一个成员是在这里从0到10000的整数索引'i'。如果默认的ctor已经被使用,那么'first'成员将为零,并且由于地图不能包含重复的键,所以只有一个映射条目。由于我们知道已经打印了10000个,我们知道默认对ctor没有被使用。 – MSalters

3

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,但我认为它有些像...

+0

这实际上是STL'map'类,而不是'std :: map'。后者受到前者的启发,但存在细微的差异。这个问题是关于一分钟的细节。但是,是的,因为它发生在这里没有分歧。 – MSalters

+0

你是对的,有很多STL版本,SGI,STLPort,微软版本等。 – kaitian521

+0

如果微软有一个STL派生的库,那是20年前。 (也许VC4,不记得细节)。他们绝对转而使用C++ 98标准库实现VC6实现Dinkumware。 – MSalters

0

在C++ 14标准,部分[map.access]文本是:

T& operator[](const key_type& x);

  1. 效果:如果没有键相当于x在地图,插入value_type(x, T())到地图。

所以,也由约瑟夫·加尔文的回答说,表达mapped_type()的结果是什么插入。这种初始化称为value-initialization

对于类的类型,值初始化的含义并不像其他答案中那样简单。它取决于类类型具有的构造函数类型,以及该类是否为聚合,正如cppreference链接所解释的。

对于int就像在这个问题中那样,值初始化意味着int被设置为0