2010-11-23 115 views
13

今天我創建了一個映射,其中值類型沒有默認構造函數。我很驚訝我不能使用operator []將元素插入到這個映射中,但我不得不使用insert方法。std :: map的類型要求

那麼,對於std :: map的鍵和值類型的要求究竟是什麼?

下面是簡單的例子:

#include <map> 

struct A 
{ 
    A(int){} 
}; 

int main() 
{ 
    std::map< int, A > m; 
    A a1(2); 
    A a2(3); 
    A a3(4); 
    m[5] = a1; 
    m[3] = a2; 
    m[2] = a3; 
} 

我編譯如下:

[[email protected] tmp]$ g++ b5.cpp -Wall -Wextra -ansi -pedantic 
/usr/lib/gcc/i386-redhat-linux/4.3.0/../../../../include/c++/4.3.0/bits/stl_map.h: In member function ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = A, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, A> >]’: 
b5.cpp:14: instantiated from here 
/usr/lib/gcc/i386-redhat-linux/4.3.0/../../../../include/c++/4.3.0/bits/stl_map.h:419: error: no matching function for call to ‘A::A()’ 
b5.cpp:5: note: candidates are: A::A(int) 
b5.cpp:4: note:     A::A(const A&) 

回答

8

operator[]確實需要默認構造性,因爲這種方法任務的語義,如果該鍵不但是存在,則創建適當的條目。因此:

map<TKey, TValue> mymap; 
TKey foo = …; 
TValue& x = mymap[foo]; 

將創建並存儲一個新的對象TValue()如果foo沒有在地圖上存在,並返回對它的引用。

5

這個網站做出了巨大的STL參考:http://www.sgi.com/tech/stl/

基本上,它說,地圖需要有強制性的2個型參數,KeyData。丹尼爾說,Data需要Assignable。但是,Key被描述爲需要是可以與Compare類型一起使用的類型,即,Compare指定其參數類型爲Key的函數對象。在這種情況下,功能對象的默認Comparestd::less<T>,它是Strict Weak Ordering,它使用operator<比較T類型的對象。因此,如果你不改變Compare類型,即使用默認的,std::less<T>將與Key類型使用,因此operator<Key類型使用,因此Key需要與operator<媲美。

希望有幫助!我知道這有點無端,我不是故意居高臨下,但我只是想確定如何去推理這件事,這是絕對清楚的。

+2

原則上這是一個很好的答案,但它不能解釋爲什麼OP的代碼失敗。 – 2010-11-23 10:28:16