2010-04-15 108 views
9

我有一個小程序,我想執行測試的東西有問題的std ::地圖和std ::對

#include <map> 
#include <iostream> 
using namespace std; 

struct _pos{ 
     float xi; 
     float xf; 

     bool operator<(_pos& other){ 

       return this->xi < other.xi; 
     } 
}; 

struct _val{ 

     float f; 
}; 

int main() 
{ 
     map<_pos,_val> m; 

     struct _pos k1 = {0,10}; 
     struct _pos k2 = {10,15}; 

     struct _val v1 = {5.5}; 
     struct _val v2 = {12.3};                 

     m.insert(std::pair<_pos,_val>(k1,v1)); 
     m.insert(std::pair<_pos,_val>(k2,v2)); 

     return 0; 
} 

的問題是,當我嘗試編譯它,我得到以下錯誤

$ g++ m2.cpp -o mtest 
In file included from /usr/include/c++/4.4/bits/stl_tree.h:64, 
       from /usr/include/c++/4.4/map:60, 
       from m2.cpp:1: 
/usr/include/c++/4.4/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = _pos]’: 
/usr/include/c++/4.4/bits/stl_tree.h:1170: instantiated from ‘std::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = _pos, _Val = std::pair<const _pos, _val>, _KeyOfValue = std::_Select1st<std::pair<const _pos, _val> >, _Compare = std::less<_pos>, _Alloc = std::allocator<std::pair<const _pos, _val> >]’ 
/usr/include/c++/4.4/bits/stl_map.h:500: instantiated from ‘std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const std::pair<const _Key, _Tp>&) [with _Key = _pos, _Tp = _val, _Compare = std::less<_pos>, _Alloc = std::allocator<std::pair<const _pos, _val> >]’ 
m2.cpp:30: instantiated from here 
/usr/include/c++/4.4/bits/stl_function.h:230: error: no match for ‘operator<’ in ‘__x < __y’ 
m2.cpp:9: note: candidates are: bool _pos::operator<(_pos&) 
$ 

我認爲聲明運營商<的關鍵將解決問題,但它仍然存在。

什麼可能是錯的?

在此先感謝。

+5

在C++中以雙下劃線開頭的所有標識符,一個下劃線跟着一個大寫字母或一個下劃線,然後在全局命名空間小寫字母被保留用於執行。標識符'_pos'和'_val'應該被改變。 – 2010-04-15 07:17:13

+0

@大衛·羅德里格斯。謝謝,會做,並牢記在心。 – Tom 2010-04-15 13:22:50

回答

25

問題是這樣的:

bool operator<(_pos& other) 

應該是這樣的:

bool operator<(const _pos& other) const { 
//    ^^^^    ^^^^^ 

沒有第一const,比較(ba < b)的右手側不能const,因爲沒有const該函數可能會修改其參數。

沒有第二const,比較(aa < b)的左手側不能const,因爲沒有const函數可以修改this

從內部來看,地圖的關鍵字總是const


應該指出,你應該更喜歡使用非成員函數。也就是說,更好的是一個自由功能:

bool operator<(const _pos& lhs, const _pos& rhs) 
{ 
    return lhs.xi < rhs.xi; 
} 

在與你的類相同的命名空間。 (在我們的例子,只是它的下面。)


順便說一句,在C++就沒有必要用struct前綴結構類型變量的聲明。這是完美的,首選:

_pos k1 = {0,10}; 
    _pos k2 = {10,15}; 

    _val v1 = {5.5}; 
    _val v2 = {12.3}; 

(雖然你的類型名稱在一個非正統的方式固然命名爲:P)


最後,你應該更喜歡做對的make_pair效用函數:

m.insert(std::make_pair(k1,v1)); 
    m.insert(std::make_pair(k2,v2)); 

它不需要寫出對的類型,而且通常更容易閱讀。 (特別是當更長的類型名稱出現時。)

+0

感謝您的額外提示。 – Tom 2010-04-15 05:52:33

+0

@Tom:沒問題,我添加了更多。 :P – GManNickG 2010-04-15 06:04:56

+0

在這種情況下,下標符號可能比直接使用插入符號要更簡潔:'m [k1] = v1;米[K2] = V2;'。 – 2010-04-15 06:12:26

4

小於運算符的簽名需要爲bool operator<(const _pos& other) const,否則map不能在const函數中使用此運算符,因爲此成員函數被聲明爲非const。

4

我認爲你的運算符<的定義是錯誤的 - 右手邊(在這種情況下的參數)應該被標記爲const並且它應該是一個const成員函數,例如,

bool operator<(const _pos& other) const{ 

      return this->xi < other.xi; 
    }