2012-08-23 16 views
8

我正在使用集合。我使用一個自定義結構作爲關鍵。我插入一個值並試圖找到插入的值。但似乎從未找到這個元素。C++ std :: set查找函數重載==運算符

我已經覆蓋了==運算符和<運算符。

這裏是結構的代碼:

struct distance_t 
{ 
public: 
int id; 
double distance; 

bool operator<(const distance_t& rhs) const 
{ 
    if(distance < rhs.distance) 
     return true; 
    else 
     return false; 
} 

bool operator==(const distance_t& rhs) 
{ 
    if(id == rhs.id) 
     return true; 
    else 
     return false; 
} 
}; 

這是主要

int main() 
{ 
    set<distance_t> currentSet; 

    distance_t insertDistance; 
    insertDistance.id =1; 
    insertDistance.distance = 0.5; 

    currentSet.insert(insertDistance); 

    distance_t findDistance; 
    findDistance.id = 1; 

    assert(currentSet.find(findDistance) != currentSet.end()); 
} 

它總是失敗的斷言語句的代碼。我究竟做錯了什麼?

編輯 - 現在我知道它根本不使用==運算符。這是我想要的。我需要按距離排序數據結構。但我應該可以使用id將其刪除。有沒有乾淨的方法或已有的數據結構來做到這一點?

+2

風格建議:如果你有'if(expr)return true;否則返回false;'你可以簡單地做'return expr;' – Blastfurnace

+1

只是'return id

+0

@Blastfurnace你也不需要括號。 –

回答

8

它失敗,因爲你的小於對比使用distance_t::distance,你不是在findDistance設置:

distance_t findDistance; 
findDistance.id = 1; 

std::set沒有任何東西使用operator==。它只使用operator<。所以你必須改變它的邏輯來使用distance_t::id

如果您想通過id不改變設置的順序進行搜索,您可以使用std::find

set<distance_t>::iterator it = std::find(currentSet.begin(), 
             currentSet.end(), 
             findDistance); 

這將使用你的operator==。請記住,這具有線性時間複雜性。

+0

我想用距離來排列元素,但希望id找到元素。這可能嗎? –

+1

@TheFlyingDutchman排序用於查找(集合是一棵二叉樹)。所以不可能有分離的排序和查找。你可以將'id'併入到排序邏輯中,這取決於你想要達到的目標。 – juanchopanza

+1

@TheFlyingDutchman你可以讓'operator <'先看看距離,如果它們相等,看看id。這將保留您要查找的訂單。 (還要改變'operator =='來查看這兩個字段。)但是,這意味着你不能搜索你是否只有id。 – hvd

4

因爲operator==根本沒有被調用。比較元素如下:

!(a < b) && !(b < a) 

換句話說,它使用operator<

1

由於您尚未將值分配給findDistance.distance,所以較少比較的結果未定義。

請注意,您定義等於和小於比較運算符是危險的,因爲定義distance_t實例的結果是不一致的。一個例子是兩個距離相同但ID不同的實例。