在爲map
中的自定義鍵重載operator<
時,爲什麼參數和函數類型都需要const
?std :: map中的自定義鍵,重載<運算符
回答
std::map<K, V>
的value_type不是您想象的std::pair<K, V>
,而是實際std::pair<const K, V>
。 因此,在鍵上調用的任何比較都會處理const對象。
現在,當編譯器看到
a < b
和a
至少一個或b
是用戶定義類型的,編譯器調用任一
operator < (a, b); //(1)
或
a.operator < (b); //(2)
(如果這兩個都可用,則出現錯誤d)。
一個非常量成員函數,包括任何運算符,可以在非常量對象上調用只有。因此,因爲a
是不變的,所以要求在//2
的情況下將該函數聲明爲const。由於b
也是常量,因此參數必須是常量引用,因爲非常量引用不能綁定到常量對象。因此,這兩個常量的要求。
該參數除了是const以外還有其他選項。它可以通過值來取參數,但這意味着不必要的複製。同樣,如果您選擇聲明非成員operator <
,則應該通過const引用(推薦)或值採用這兩個參數。
據我瞭解,const reference
的參數類型提供2個用途:
- 從它告訴,參數是不可修改的內部函數體和任何這樣的奇遇會產生編譯器錯誤簽名。
- 沒有額外的不必要的
key
類型的複製。
成員函數由const
以便你仍然可以做一個find
(或任何其它純讀(除非修改mutable
構件)的操作)一個const
地圖對象上調用。如果沒有那個const,試圖在const map對象上調用這些成員函數時,會導致編譯錯誤。
當您嘗試創建自定義比較函數時,不需要全局或非成員函數的const
。
bool operator<(const Key& a, const Key& b) /* no const required here*/ {....}
const
一個功能是隻適用於成員函數,因爲它使this
指針或實例的const
,其不能成爲全局或非構件比較運算符
CONST在一種說法是功能看好它的主叫方不會修改傳入的參數時,參數按引用傳遞,以避免額外的副本,但不會修改它往往是需要的,例如:
void function(const Type& var)
{
// can't modify var here, but can read and call its const methods (see below)
}
方法聲明中的Const是一種方法,承諾不修改它所調用的對象的內部狀態。例如
void Class::function(const Type& var) const
{
// can't modify var here
// can't modify "this" here (call other non const methods or change member variables)
}
那些承諾可以被打破(這是C++中,我們所談論的畢竟)鑄造常量性了,但是這是意圖反正。
總是要求儘可能少的東西是個好主意。如果方法不改變一個對象 - 聲明它爲const,那麼你可以在該類的一個const實例上調用這個方法(例如,當它作爲一個const引用傳遞給其他地方時)。
在std :: map上定製operator <
的情況下,不能在參數中使用非const引用的原因是因爲std :: map會在一個或多個自己的方法中調用你的運算符,被自己聲明爲const。編譯器不允許它將const對象傳遞到不承諾不修改它的函數中。
你不能聲明operator <
本身非const的原因(假設它不是一個獨立函數,而是你自定義類的一個方法用作鍵)是一樣的 - std :: map已經答應不要修改密鑰(這會對一個排序造成嚴重破壞),所以它不能調用任何不能保證不變的方法。
定製operator <
當用於排序容器內部也有其他要求 - 它必須滿足LessThanComparable概念。
- 1. 重載運算符<<用於打印自定義異常
- 2. std :: setw整個運算符<<用戶自定義類型
- 3. 重載運算符<< ostream的
- 4. 重載<<運算符的std :: ostream的
- 5. 重載運算符<< - 必須是二元運算符
- 6. 重載運算符<<數組
- 7. 運算符重載C++(<<)
- 8. 重載自定義類中的ostream運算符
- 9. 重載運算符<<爲集
- 10. 在C++中重載<<運算符
- 11. 重載運算符<< operator ==和operator!=
- 12. std :: list的重載括號運算符
- 13. std :: shared_ptr上的重載運算符==
- 14. 重載已定義的運算符
- 15. 繼承自std :: vector <T>和重載運算符[]用於自定義索引
- 16. 重載運算符<<:不能綁定'std :: basic_ostream <char>'左值爲'std :: basic_ostream <char> &&'
- 17. ASP.net MVC自定義字符串輸出重載運算符<%= h
- 18. C++重載運算符<<和運算符>>
- 19. 重載C++插入運算符(<<)
- 20. 重載運算符<< ostream語法
- 21. >><<和運算符重載
- 22. 如何重載<<運算符?
- 23. 重載運算符<<在C++
- 24. 有關在運算符重載定義
- 25. 不匹配運算符<< in out使用運算符重載C++
- 26. 錯誤<<運算符重載返回一個std ::字符串
- 27. 在派生類中重載運算符<<
- 28. 運算符重載
- 29. C++運算符在已重載的運算符中重載
- 30. 運算符<<和std :: stringstream引用?
const引用表示沒有額外的參數副本,並且不能意外地在比較函數內部更改它們 – KIIV
要比較兩個常量鍵,您需要兩個常量,每個參數一個。 –
函數後面的'const'意味着該函數不會修改正在進行比較的對象 – smac89