C++ C++;重写特定数据类型的std::set的默认小于参数

C++ C++;重写特定数据类型的std::set的默认小于参数,c++,templates,C++,Templates,我有很多代码创建一个std::set。现在默认情况下,它使用less对指针值集进行排序。这会在我们的工具中产生问题。我想为所有set提供一个默认比较器my_less,而不必去更改所有代码。所以我尝试了模板专门化: namespace std { template<> class set<Port*> : public set<Port*, my_less> {}; }; 解决这个问题的好方法是什么(我可以为构造函数复制代码,但这看起来并不干净) 除了

我有很多代码创建一个
std::set
。现在默认情况下,它使用
less
对指针值集进行排序。这会在我们的工具中产生问题。我想为所有
set
提供一个默认比较器
my_less
,而不必去更改所有代码。所以我尝试了模板专门化:

namespace std {
    template<> class set<Port*> : public set<Port*, my_less> {};
};
解决这个问题的好方法是什么(我可以为构造函数复制代码,但这看起来并不干净)

除了以下方法外,还有其他方法可以实现我的目标:

template<> class set<Port*> : public set<Port*, my_less> {};
模板类集合:公共集合{};

以下是我对这个问题的一般解决方案

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

// structs
struct my_struct
{
    int a;
    int b;
};

struct my_second_struct
{
    int a;
    int b;
};

bool operator<(const my_second_struct& m1, const my_second_struct& m2)
{
    return m1.b < m2.b;
}

// alias helper
template <typename T>
using custom_comparator_t = std::function<bool(const T, const T)>;

// function to proxy already defined operator to pointers
template<typename T>
auto get_pointer_less()
{
    return [](const T* v1, const T* v2) -> bool { return (*v1) < (*v2); };
}

// this is generic solution
template<typename T>
using pointer_set = std::set<T*, custom_comparator_t<T*>>;

// and final config
template<typename T>
auto get_pointer_set()
{
    return pointer_set<T>( get_pointer_less<T>() );
}

template<typename T, typename _T>
void fill_and_display(_T& s)
{
    s.insert(new T{10, 20});
    s.insert(new T{20, 10});
    s.insert(new T{0, 100});
    s.insert(new T{100, 0});

    std::cout << "set: ";
    for (const T *ms : s)
        std::cout << "( " << ms->a << " ; " << ms->b << " )";
    std::cout << std::endl;
}

int main()
{
    // First option, create custom less operator inline
    std::set<my_struct *, custom_comparator_t<my_struct *>> myset(
        [](const my_struct *ms1, const my_struct *ms2) { return ms1->a < ms2->a; }
    );

    fill_and_display<my_struct>(myset);

    // Second option, reuse, already defined less operator
    std::set<my_second_struct *, custom_comparator_t<my_second_struct*>> my_second_set(
        get_pointer_less<my_second_struct>()
    );

    fill_and_display<my_second_struct>(my_second_set);

    // generic colution for second set
    auto my_third_set = get_pointer_set<my_second_struct>();

    fill_and_display<my_second_struct>(my_third_set);

    return 0;
}
#包括
#包括
#包括
//结构
结构我的结构
{
INTA;
int b;
};
结构我的第二个结构
{
INTA;
int b;
};
bool算子bool{return(*v1)<(*v2);};
}
//这是通用的解决方案
模板
使用指针\u set=std::set;
//和最终配置
模板
自动获取指针集()
{
返回指针集(get_pointer_less());
}
模板
空白填充和显示(\u T&s)
{
s、 插入(新的T{10,20});
s、 插入(新的T{20,10});
s、 插入(新的T{0,100});
s、 插入(新的T{100,0});

std::cout自C++11以来,您可以通过以下方式轻松继承构造函数:

namespace std {
    template<> class set<Port*> : public set<Port*, my_less> {
        public: using set<Port*, my_less>::set;
    };
};
名称空间std{
模板类集:公共集{
public:使用set::set;
};
};

借用Python的一点哲学:显式比隐式好。继续,将所有声明更改为使用自定义比较器,忘记尝试将其自动化。请尽可能使用
auto
,以便声明的额外复杂性不会受到太大影响。例如,在类中使用迭代器时。我想知道专业化
std::less
是否是您的一个选择。甚至重载
操作符,您也可以根据代码库的组织,将
端口*
放入包装器对象中(例如
PortPtrWrapper
)并重载
操作符使用PortSet=set
生成别名
。在任何适当的编辑器中使用find and replace,最好执行正确的修复。感谢大家的帮助。这是我关于堆栈溢出的第一个问题,大家都很好
namespace std {
    template<> class set<Port*> : public set<Port*, my_less> {
        public: using set<Port*, my_less>::set;
    };
};