考慮下面的代碼:初始化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