2013-02-09 40 views
0

。 但是,當我用vector替換set,因此使用push_back函數代替insert函數時,一切正常。任何人都可以解釋我做錯了什麼? 謝謝你的建議。問題與C++當我嘗試編譯下面的代碼設置容器

+0

如果你不關心排序,你可能想嘗試一下'std :: unordered_set',這在你看來並不在這裏,根據你得到的錯誤來判斷,我已經從編譯這個錯誤我的腦子。 – chris 2013-02-09 03:34:28

+0

@chris因爲你必須提供一個散列和相等運算符,所以它可能會使用'std :: unordered_set'更多的工作。 – Rapptz 2013-02-09 03:44:08

+0

@Rapptz,確實,儘管訂購在我看來並不像它在這裏很突出。 – chris 2013-02-09 03:46:33

回答

3

std::set將其值存儲在已排序的二叉樹中,因此它需要知道如何比較它所保存的值。默認情況下,它使用std::less作爲比較函數,對於非專用用戶定義類型,它嘗試調用operator<。所以,說一套如何比較你的對象最簡單的方法是定義一個operator<爲你的類:

template <class T, class S> 
class Property 
{ 
public: 
    pair<T,S> p; 

    Property(T t, S s) { p = make_pair(t,s);} 

    bool operator<(const Property<T,S>& rhs) const 
    { 
     return p < rhs.p; 
    } 
}; 

然而,也有告訴std::set如何比較你的類型的其他方式。一個是專門的std::less模板類:

namespace std { 
template<typename T,typename S> 
struct less<Property<T, S> > 
{ 
    bool operator()(const Property<T, S>& lhs, const Property<T,S>& rhs) const 
    { 
     return lhs.p < rhs.p; 
    } 
}; 
} 

另一種是用正確的簽名功能,或具有與正確的簽名定義的operator()一個類來替代默認的比較類型。這是事情開始變得醜陋的地方。

// Comparison function 
template<typename T, typename S> 
bool property_less_function(const Property<T,S>& lhs, const Property<T,S>& rhs) 
{ 
    return lhs.p < rhs.p; 
} 

// Comparison functor 
template<typename T, typename S> 
struct PropertyLess 
{ 
    bool operator()(const Property<T,S>& lhs, const Property<T,S>& rhs) const 
    { 
     return lhs.p < rhs.p; 
    } 
}; 

int main() 
{ 
    // Set using comparison function. 
    // Have to pass the function pointer in the constructor so it knows 
    // which function to call. The syntax could be cleaned up with some 
    // typedefs. 
    std::set<Property<std::string, std::string>, 
     bool(*)(const Property<std::string, std::string>&, 
       const Property<std::string, std::string>&)> 
      set1(&property_less_function<std::string, std::string>); 

    // Set using comparison functor. Don't have to pass a value for the functor 
    // because it will be default constructed. 
    std::set<Property<std::string, std::string>, PropertyLess<std::string, std::string> > set2; 
} 

請記住,任何低於你使用的功能,該功能必須定義您的類型strict weak ordering

+0

非常感謝您的明確解釋。 – 2013-02-09 21:54:25

2

爲了在std::set中插入一些東西,您需要定義operator<

例如該編譯罰款GCC 4.7.2:

#include <iostream> 
#include <set> 
#include <vector> 

using namespace std; 

template <class T, class S> 
class Property 
{ 
public: 
    pair<T,S> p; 
    Property(T t, S s) { 
     p = make_pair(t,s); 
    } 
    bool operator<(const Property& p2) const { 
     //Something naive.. 
     return p < p2.p; 
    } 

}; 

int main() 
{ 
set< Property<string, string> > properties; 
Property<string, string> name("name", "Andy"); 

properties.insert(name); 

} 

另一種方法是使用std::unordered_set儘管這將要求您提供鑰匙並定義operator==哈希值。

+0

代碼不會在我的VC編譯:) – billz 2013-02-09 03:53:58

+0

@billz當然,我只嘗試過GCC 4.7.2。 – Rapptz 2013-02-09 03:55:02

+0

對已經有'operator <',爲什麼不只是'p billz 2013-02-09 03:56:58