【问题标题】:Looking for "is_comparable" typetrait寻找“is_comparable”类型特征
【发布时间】:2015-10-17 14:37:45
【问题描述】:

我正在寻找“is_comparable”类型特征,但找不到。

很容易构建一个检查类的operator== 是否已实现,但这不包括全局定义的运算符。

是不是不可能实现is_comparable typetait?

【问题讨论】:

    标签: c++11 typetraits


    【解决方案1】:

    我认为你的意思是,对于两种类型 LR 和 这些类型的对象lhsrhs 将分别产生true 如果 lhs == rhs 将编译,false 否则。你很感激 理论上lhs == rhs 可以编译,即使rhs == lhslhs != rhs, 没有。

    在这种情况下,您可能会实现如下特征:

    #include <type_traits>
    
    template<class ...> using void_t = void;
    
    template<typename L, typename R, class = void>
    struct is_comparable : std::false_type {};
    
    template<typename L, typename R>
    using comparability = decltype(std::declval<L>() == std::declval<R>());
    
    template<typename L, typename R>
    struct is_comparable<L,R,void_t<comparability<L,R>>> : std::true_type{};
    

    这应用了一个流行的 SFINAE 模式来定义特征 回复this question

    一些插图:

    struct noncomparable{};
    
    struct comparable_right
    {
        bool operator==(comparable_right const & other) const {
            return true;
        }
    };
    
    struct any_comparable_right
    {
        template<typename T>
        bool operator==(T && other) const {
            return false;
        }
    };
    
    bool operator==(noncomparable const & lhs, int i) {
        return true;
    }
    
    #include <string>
    
    static_assert(is_comparable<comparable_right,comparable_right>::value,"");
    static_assert(!is_comparable<noncomparable,noncomparable>::value,"");
    static_assert(!is_comparable<noncomparable,any_comparable_right>::value,"");
    static_assert(is_comparable<any_comparable_right,noncomparable>::value,"");
    static_assert(is_comparable<noncomparable,int>::value,"");
    static_assert(!is_comparable<int,noncomparable>::value,"");
    static_assert(is_comparable<char *,std::string>::value,"");
    static_assert(!is_comparable<char const *,char>::value,"");
    static_assert(is_comparable<double,char>::value,"");
    

    如果您希望特征要求相等是对称的并且不等式 也存在并且是对称的,你可以看看如何自己阐述它。

    【讨论】:

    • 感谢您的回答,但它不起作用。尝试使用 gcc 编译此代码时,即使您的 static_assert 也会失败。问题似乎是没有得到评估的“std::declval() == std::declval()”。有趣的是,clang-3.8 抛出了一个编译异常,正如我所料。
    • @Gene Odd,它用gcc 5.2 liveclang 3.6 live 为我编译。也许你可以发布你失败的编译?
    • 有趣...我使用了 gcc 4.9.2,它也抱怨 static_assert。我的本地示例也稍微复杂一些。我在最后添加了一个pair定义,这使得clang 3.6 live也意外失败:goo.gl/OKsuIU
    • @Gene Pair2 是一个断路器,是的。 sfinae 为时已晚。如果有人成功实现了 [EqualityComparable 概念] (en.cppreference.com/w/cpp/concept/EqualityComparable),他们一定已经破解了这个,但显然我没有。
    • 感谢您的帮助。还有一个问题:为什么 Pair2 是断路器?是不是因为它的比较函数是作为非成员函数实现的?
    猜你喜欢
    • 2014-02-18
    • 2018-08-04
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 2020-01-10
    • 2017-07-19
    • 2014-06-10
    • 1970-01-01
    相关资源
    最近更新 更多