2017-10-08 161 views
0

我正在嘗試返回std::map的最大值。爲什麼C++編譯器在參數中不使用const時編譯失敗?

int main() { 
    int N; 
    cin >> N; 
    map<int,int > m; 
    while(N--) { 
     int x; cin >> x; 
     m[x]++; 
    } 
    cout << max_element(m.begin(), m.end(), pred)->first; 
    return 0; 
} 

如果我定義pred這樣的,它的工作原理:

bool pred(const pair<int,int>& lhs, const pair<int,int>& rhs){ 
    return lhs.second < rhs.second; 
} 

然而,這不起作用:

bool pred(pair<int,int>& lhs, pair<int,int>& rhs){ 
    return lhs.second < rhs.second; 
} 

我不明白爲什麼const允許它的工作。

+2

將參數更改爲pair &',然後重試。顯然,map鍵是一個'const'。顯然,您不能在地圖上更改某個特定值的密鑰。 –

+0

是的,但我不想改變任何東西。爲什麼我需要const? – sbryan1

+0

您需要const,因爲您無法在程序的任何部分合法地轉換或轉換const。這就是所謂的const正確性,在C++中它是類型安全的一部分。如果您嘗試將const事傳遞給一個採用非const引用的函數,那麼這是一個編譯錯誤。 const的東西不能綁定到非const引用。 –

回答

0

std::map<K, V>的值類型不是std::pair<K, V>而是std::pair<K const, V>:您無法更改std::map<K, V>元素的密鑰。你應該用正確的值類型,請pred()函數的參數:

bool pred(std::pair<int const, int>& lhs, std::pair<int const, int>& rhs) { ... } 

,或最好

bool pred(std::map<int, int>::reference lhs, std::map<int, int>::reference rhs) { ... } 

pred()函數不改變的參數。相應地,它可以也可能應該採用const&的參數,因爲它允許使用std::map<K, V> const。但是,僅在非const地圖中使用該函數時,假設它使用正確的值類型,則不需要這樣做。

std::pair由於具有從其他std::pair類型轉換運算符,它可以[隱式]轉換從std::pair<int const, int>std::pair<int, int>。但是,結果爲臨時std::pair<int, int>,不能綁定到非const參考。對於一對int值,可能沒有大的性能差異,但隱式轉換可能很容易成爲主要性能問題,例如,當鍵或值包含某種形式的容器時。

+0

好的,謝謝。這很清楚。在哪裏可以看到這些「隱式」轉換,其中有必要使用'const',而不管我是否真的打算改變這個值。 – sbryan1

+0

@ sbryan1:各種關聯容器的'value_type'是我知道的最常見的情況。在其他情況下,類元組類型包含的成員可能與它所使用的類型不完全匹配。例如,將'std :: tuple '分配給'std :: tuple '時,你會得到一個類似的轉換,產生一個臨時的。 順便說一句,在Stackoverflow的貨幣不是「謝謝」,但接受答案,如果你認爲他們是體面的,也可能投票。 –