如何比较两个比较两个标准::设置

How to compare two Compare of two std::set

本文关键字:两个 比较 设置 标准 何比较      更新时间:2023-10-16

当我使用容器std::set时,我想比较set的Compare.set的一个定义如下:

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;

我们知道 Compare 是集合中元素的排序参数,它可以是 STL 中的函数对象或用户提供它。只有一个对函数对象的请求是实现 opeartor()。在程序中,我可以得到比较使用公共成员功能value_compare value_comp() const我的问题是如何区分两组的排序参数(两组是否使用相同的排序参数)?

std::set有一个key_compare typedef 来简单地Compare

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

或在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!");

演示

#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;
}

结果输出:

1
0

直接key_comp获取 std::set 的比较,然后将它们与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;
}

您可以判断两个比较函数是否是同一类型(如其他答案所示),但这并不意味着它们是相同的函数。以下代码编译不带错误,即使它们使用不同的排序条件。

#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, "" );
    }
}

和打印:

3 2 1
1 2 3