2009-12-29 22 views
0

所以我正在研究一個項目,並且我必須在類對象上使用set庫。這些對象有許多屬性,ID就是其中之一。如何使用類作爲在set :: find()上使用的值? - C++

我想要做的是通過它的ID搜索「set」內的對象。問題設置只有找到,我不知道如何搜索一個ID這種方式,因爲我不得不使用find(類對象),而不是(int)。我試圖搞亂類操作符,把它當作一個對象來讀取,但是找不到方法。

另外,我想過算法:: find_if,但這只是檢查每個元素從開始到結束,而不是使用設置的「樹」搜索功能,對不對?

在此先感謝。

回答

0

你需要爲你的類創建一個構造函數,它只需要int作爲它的唯一參數。這樣做可以將int隱式轉換爲您的班級,從而可以根據要求撥打std::set::find(int)

例如:

#include <iostream> 
#include <set> 

class Foo { 
    public: 
    /* Normal constructor */ 
    Foo(const char * s, int i) : str(s),id(i) {} 
    /* Special constructor for implicit conversion */ 
    Foo(int i) : str(0),id(i) {} 
    /* Make Foo usable with std::set */ 
    bool operator<(const Foo& f) const { return f.id<id; } 
    /* Make Foo printable */ 
    friend std::ostream& operator<<(std::ostream& o, const Foo& f); 
    private: 
    const char * str; 
    int id; 
}; 
std::ostream& operator<<(std::ostream& o, const Foo& f) { 
    return o << "(" << f.str << " " << f.id << ")"; 
} 

typedef std::set<Foo> FooSet; 
int main(void) { 
    FooSet s; 
    s.insert(Foo("test",1)); 
    s.insert(Foo("asdf",7)); 
    s.insert(Foo("spam",3)); 
    for (int i=0; i<10; ++i) { 
    /* Note that searching is done via FooSet::find(int id) */ 
    FooSet::const_iterator f = s.find(i); 

    std::cout << "Searching for id " << i << ": "; 
    if (f==s.end()) 
     std::cout << "absent"; 
    else 
     std::cout << "present " << *f; 
    std::cout << std::endl; 
    } 
    return 0; 
} 

這產生了:

Searching for id 0: absent 
Searching for id 1: present (test 1) 
Searching for id 2: absent 
Searching for id 3: present (spam 3) 
Searching for id 4: absent 
Searching for id 5: absent 
Searching for id 6: absent 
Searching for id 7: present (asdf 7) 
Searching for id 8: absent 
Searching for id 9: absent 
+0

這完全是我想知道的。現在正在工作,謝謝! – user228938 2009-12-29 21:34:21

2

您必須使用第二個模板參數來指定比較函子。看你的ltstr例子this page

+0

的事情是我已經做了,由於這是需要在設置正確插入類。這也是工作,因爲它根據他們的ID插入它們,但是發現它仍然不會讓我使用find(int)... – user228938 2009-12-29 19:32:46

+0

是的,你必須用你想要的ID做一個虛擬實例。 – Pace 2009-12-29 19:34:35

2

從你的描述中,你可能要考慮使用一個std :: map或std :: unordered_map,其中你的「ID」作爲鍵,你的類對象作爲值。

+0

我同意這一點,但他的問題表明他必須使用std :: set。 – 2009-12-29 19:39:34

2

如果你的類是一組,那麼你已經定義了運營商<或提供了一個具體的比較器使用比較元素已經compatable嚴格的弱秩序。

struct X 
{ 
    X(int pid): id(pid) {} 
    int id; 
    bool operator<(X const& rhs) { return this->id < rhs.id;} 
}; 

std::set<X> data; 
std::set<X>::const_iterator find = data.find(X(12)); 
if (find != data.end()) 
{ 
     // You found the item 
} 

這在你需要的方式,你可以很容易地與特定的ID和運營商<(或比較器)創建的臨時對象來定義X的缺點僅僅是ID的嚴格弱序。

另一種方法是使用std :: find_if()使用自定義比較器:

struct TestXID 
{ 
    TestXID(int testId): tid(testId) {} 
    bool operator()(X const& item) const {return tid == item.id;} 
    int tid; 
}; 

std::set<X>::const_iterator find = std::find(data.begin(),data.end(),TestXID(5)); 
if (find != data.end()) 
{ 
     // You found the item 
} 
+0

正如前面提到的海報,std :: find_if()的缺點是它在複雜度上是線性的,與std :: set :: find()的O(log n)相反。 – mrkj 2009-12-29 20:25:07