2011-02-27 69 views
61

我試圖使用operator []訪問const C++映射中的元素,但此方法失敗。我也試圖用「at()」來做同樣的事情。它這次工作。但是,我找不到有關使用「at()」訪問const C++映射中的元素的任何參考。 「at()」是C++ map中新增的函數嗎?我在哪裏可以找到關於此的更多信息?非常感謝你!C++常量映射元素訪問

一個例子可以是以下各項:

#include <iostream> 
#include <map> 

using namespace std; 

int main() 
{ 
     map<int, char> A; 
     A[1] = 'b'; 
     A[3] = 'c'; 

     const map<int, char> B = A; 

     cout << B.at(3) << endl; // it works 
     cout << B[3] << endl; // it does not work 

} 

對於使用 「B [3]」,它在編譯期間返回如下錯誤:

t01.cpp:14: error: passing ‘const std::map, std::allocator > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = char, _Compare = std::less, _Alloc = std::allocator >]’ discards qualifiers

使用的編譯器爲g ++ 4.2.1

回答

80

at()是C++ 11中的一個新方法,用於std::map

而不是插入一個新的默認構造元素作爲operator[]如果具有給定鍵的元素不存在,它會拋出std::out_of_range異常。 (這是類似於at()dequevector的行爲。)

由於這種行爲是有意義的,那裏是一個const超載at(),不像operator[]總是有更改地圖的潛力。

+0

可以讓「at」返回一個默認值而不是拋出異常嗎? – user1202136

+0

'at()'應該只用C++ 11 – Deqing

+0

我在VS2013中使用'at()'來設置使用VS2010工具包的項目。我認爲這意味着我沒有使用C++ 11 ...但它編譯...? – thomthom

27

如果一個元素不存在於map中,則operator []將會添加它 - 這顯然不能在const映射中工作,因此C++沒有定義運營商的const版本。這是編譯器類型檢查器防止潛在運行時錯誤的一個很好的例子。

在你的情況,你需要使用find,而不是將它是否存在,它永遠不會修改map返回(迭代器)元素。如果項目不存在,它會將迭代器返回到地圖的end()

at不存在,甚至不應該編譯。也許這是一個「編譯器擴展」(= 錯誤新的C++ 0x)。

+0

C++標準是否禁止實現在庫類中定義額外的非標準成員函數? –

+0

@Tim我相信界面是固定的,是的。 –

3

如果給定的鍵不存在,[]操作員將在映射中創建一個新條目。它可能因此改變地圖。

看到這個link