ERROR:C2678 二進制“<”: 沒有找到接受“const _Ty”類型的左操作數的運算符(或沒有可接受的轉換)


【1】復現問題

為了更精確的分析,先用最簡單的示例復現此錯誤場景,代碼如下:

 1 #include <map>
 2 #include <string>
 3 
 4 struct Section
 5 {
 6     int id;
 7     std::string code;
 8 
 9     bool operator<(const Section& rhs)
10     {
11         return id < rhs.id;
12     }
13 };
14 
15 int main()
16 {
17     std::map<Section, std::string> stdMap;
18     stdMap.insert(std::make_pair(Section{ 1 }, "kaizen1"));
19     stdMap.insert(std::make_pair(Section{ 2 }, "kaizen2"));
20     stdMap.insert(std::make_pair(Section{ 3 }, "kaizen3"));
21 
22     return 0;
23 }

編譯結果:

如上,穩定重現。

【2】分析原因

如上示例,你可能會問,明顯已經實現了運算符<的重載,為什么還編譯錯誤呢?

注意仔細分析錯誤提示內容,從"const_Ty"字樣不難看出編譯器需要const支持。

編譯器限定,運算符“<”內部只需讀取對象成員變量,體現出大小比較的原則即可,禁止對成員變量進行修改。

所以,重載運算符“<”的實現必須要求const限定。

【3】解決方案

方案一:重載運算符“<”

方案二:友元函數

為了便於對比,兩種方案代碼放在一起,如下示例:

 1 #include <map>
 2 #include <string>
 3 
 4 struct Section
 5 {
 6     int id;
 7     std::string code;
 8 
 9 #if 1
10     // 方案一:重載運算符<
11     bool operator<(const Section & rhs) const   // 注意:第二個const
12     {
13         return id < rhs.id;
14     }
15 #else
16     // 方案二:提供運算符<的友元函數
17     friend bool operator<(Section const& lhs, Section const& rhs)
18     {
19         return lhs.id < rhs.id;
20     }
21 #endif
22 };
23 
24 int main()
25 {
26     std::map<Section, std::string> stdMap;
27     stdMap.insert(std::make_pair(Section{ 1 }, "kaizen1"));
28     stdMap.insert(std::make_pair(Section{ 2 }, "kaizen2"));
29     stdMap.insert(std::make_pair(Section{ 3 }, "kaizen3"));
30 
31     return 0;
32 }

方案一、第11行:兩個const作用說明:

(1)函數加上const后綴作用是限定函數內部實現對類成員變量具有只讀權限。

(2)形參類型加上const,限定在這個函數內部對用來進行比較的“原版對象”成員做任何修改。

對於const的和非const的實參,函數都可以使用;如果不加,就只能接受非const的實參。

另外補充,引用的作用避免在函數調用時對實參的一次拷貝,提高了效率。

備注:關於const關鍵字,建議參見隨筆《const關鍵字

方案二、參見隨筆《友元》理解。

【4】觸類旁通

如果是std::vector容器中存儲自定義類型,又會有什么約束呢?

詳情參見隨筆《ERROR:2676

 

good good study, day day up.

順序 選擇 循環 總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM