2016-05-24 17 views
0

Wenn ich den Container std :: set, ich will Compare.One Definition-Set auf Vergleich wie folgt:Wie vergleichen zwei von zwei std :: Vergleichen gesetzt

template < class T,      // set::key_type/value_type 
      class Compare = less<T>,  // set::key_compare/value_compare 
      class Alloc = allocator<T>  // set::allocator_type 
      > class set; 

Wir wissen, vergleichen das ist Sortierkriterium für Elemente im Satz, es kann ein Funktionsgegenstand in der STL sein oder Benutzer liefern es. Nur eine Anforderung für Funktionsgegenstand ist, um operartor() zu verwirklichen. Im Programm kann ich Vergleiche die Öffentlichkeitsmittefunktion value_compare value_comp() const erhalten Meine Frage ist wie um die Sortierfolge von zwei zu unterscheiden (Zwei Sätze verwenden dieselbe Sortierfolge oder nicht)?

Antwort

2

std::set hat ein key_compare typedef zu Compare so einfach:

std::is_same<decltype(set_a)::key_compare, decltype(set_b)::key_compare>::value 

Oder in einem struct:

template<typename Set1, typename Set2> 
struct is_same_comparator: public std::is_same<typename Set1::key_compare, 
               typename Set2::key_compare> { }; 

using S1 = std::set<int>; 
using S2 = std::set<int, std::greater<int>>; 

static_assert(is_same_comparator<S1, S1>{}, "Oops!"); 
static_assert(is_same_comparator<S1, S2>{}, "Oops!"); 

DEMO

+0

Vielen Dank – TongChen

1
#include <type_traits> 
#include <set> 
#include <iostream> 

template<typename t> class comparator_type; 

template<typename v1, typename c1, typename a1> 
class comparator_type<std::set<v1, c1, a1>> { 

public: 

    typedef c1 type_t; 
}; 

template<typename set1, typename set2> 
constexpr bool is_same_comparators() 
{ 
    return std::is_same<typename comparator_type<set1>::type_t, 
       typename comparator_type<set2>::type_t> 
     ::value; 
} 


int main() 
{ 
    std::set<int> a, b; 
    std::set<int, std::greater<int>> c; 

    std::cout << is_same_comparators<decltype(a), decltype(b)>() << std::endl; 
    std::cout << is_same_comparators<decltype(a), decltype(c)>() << std::endl; 
} 

resultierender Ausgang:

1 
0 
+0

Warum brauchen Sie diese 'comparator_type' Zwischenstruktur, wenn Sie den comparatore Typ zugreifen kann mit' Typname set1 :: key_compare'? – Holt

+0

Vielen Dank, bevor ich es vergesse – TongChen

0

von key_comp direkt das Vergleichen von std :: fertig, sie dann mit std::is_same

#include <set> 
#include <iostream> 
#include <type_traits> 
#include <functional> 

int main() 
{ 
    std::set<int> a; 
    std::set<int, std::greater<int> > b; 
    std::set<int, std::less<int> > c; 
    std::cout << std::is_same< decltype(a.key_comp()), decltype(b.key_comp()) >::value << std::endl; 
    std::cout << std::is_same< decltype(a.key_comp()), decltype(c.key_comp()) >::value << std::endl; 
    return 0; 
} 
+0

Vielen Dank, ich möchte nur versuchen. – TongChen

0

vergleichen Sie können feststellen, ob zwei Vergleichsfunktionen vom gleichen Typ sind (wie die anderen Antworten zeigen), aber das heißt nicht, dass sie dieselbe Funktion haben. Der folgende Code kompiliert ohne Fehler, obwohl sie andere Sortierkriterien verwenden.

#include <set> 
#include <functional> 
#include <iostream> 

bool g(int a, int b) { return a > b; } 
bool l(int a, int b) { return a < b; } 

int main() { 
    static_assert(std::is_same<decltype(g), decltype(l)>::value, ""); 

    { 
    typedef std::set<int, bool(*)(int, int)> Set1; 
    Set1 sg(g); 
    Set1 sl(l); 
    static_assert(std::is_same<decltype(sg.key_comp()), decltype(sl.key_comp())>::value, ""); 
    sg.insert({1,2,3}); 
    for (int i : sg) std::cout << i << " "; std::cout << "\n"; 
    sl.insert({1,2,3}); 
    for (int i : sl) std::cout << i << " "; std::cout << "\n"; 
    } 

    { 
    typedef std::function<bool(int, int)> Comp; 
    Comp fg(g); 
    Comp fl(l); 
    static_assert(std::is_same<decltype(fg), decltype(fl)>::value, ""); 

    typedef std::set<int, Comp> Set2; 
    Set2 sg(fg); 
    Set2 sl(fl); 

    static_assert(std::is_same<decltype(sg.key_comp()), decltype(sl.key_comp())>::value, ""); 
    } 
} 

und Drucke:

3 2 1 
1 2 3