2014-09-28 80 views
1
class Test 
{ 

public: 

    int v; 
    Test(int s) 
    { 
     v = s; 
    } 

    bool operator < (const Test & b) const 
    { 
     return v < b.v; 
    } 
}; 

int main() 
{ 
    set <Test> t2; 
    return 0; 
} 

爲什麼當我重載less操作符時,我必須使用const函數?如果我不寫「const」,它不會通過編譯。所以我不知道爲什麼我必須在那裏寫「const」?爲什麼STL <set>重載運算符<函數必須是const函數?

+7

因爲在比較對象時修改對象沒有意義。 – 2014-09-28 08:46:44

回答

1

您不需要這樣做。一般建議這樣做,因爲在比較過程中不應修改對象。 set<Test>通過將const引用傳遞給operator<來滿足這個要求。

+0

一些實現barf,如果你不這樣做。 – juanchopanza 2014-09-28 08:52:11

+0

@juanchopanza:任何不允許非const的操作符<'的實現都被破壞了。在OP的情況下,問題是'set '嘗試將const引用傳遞給'operator <',而不是'operator <'本身。 – 2014-09-28 09:00:22

+0

你有一個C++標準的參考嗎?因爲這意味着gcc4.8和4.9被破壞了(我確信自從4.4版本以來我已經看到了這個)。 – juanchopanza 2014-09-28 09:09:40

4

的原因是std::set有點特殊:數值IT賣場不得更改(同樣以std::mapkey_type)。這是因爲set是一個已排序的容器,它需要知道如何對值進行排序;更改集合中的值可能會導致程序損壞,因爲set::set無法知道值已更改,因此需要重新排序。

如果允許比較函數修改值,那麼它永遠不會被使用,因爲集合中的值總是常量。

順便說一下,確實可以對值進行一些修改,特別是不影響排序順序的修改。所以如果你有一個具有自定義排序功能的結構的排序功能,你可以修改結構的其他字段,因爲排序順序將保持不變。但std::set無法理解哪些字段對排序順序很重要,哪些不是,所以整個值是常量。你可以做一些技巧,比如讓一些字段mutable來解決這個問題,但是在大多數情況下,這是不必要的(例如,你可以使用地圖來代替,而是將可修改的部分改爲value_type)。