【问题标题】:C++ determine if class is comparableC ++确定类是否具有可比性
【发布时间】:2012-02-08 23:04:48
【问题描述】:

我或多或少是 Java 程序员,所以这可能是一个愚蠢的问题,但我没有找到任何简单的解决方案。

我在 C++ 中有一个这样的类:

template<class T> class Node {...}

而且我需要 T 具有可比性 - 至少定义了 == 运算符。是否有任何 简单 方法可以做到这一点 - 或者最好的做法是什么?在 Java 中,它会是这样的:

public class Node<T extends Comparable> { ... }

感谢您的帮助!

【问题讨论】:

标签: c++ templates generics comparable


【解决方案1】:

C++ 模板为duck-typed,因此不需要接口或约束,如果存在比较运算符,编译器将使用比较运算符,如果不存在则生成错误。

另见this more detailed answer

【讨论】:

    【解决方案2】:

    如果您想避免神秘错误(当模板实例化树的深度缺乏可比性时,您经常会遇到这种错误),只需使用 enable_if:

    特别是,请查看 boost::enable_if 文档中的“启用模板类专业化”。

    您经常将 enable_if 与 type_traits 一起使用:http://www.boost.org/doc/libs/release/libs/type_traits/doc/html/index.html

    您的案例可能特别感兴趣:

    http://www.boost.org/doc/libs/release/libs/type_traits/doc/html/boost_typetraits/reference:/has_equal_to.html

    http://www.boost.org/doc/libs/release/libs/type_traits/doc/html/boost_typetraits/reference/has_not_equal_to.html

    但也请参见 has_greater、has_greater_equal、has_less、has_less_equal 等。 // 实际上我有点惊讶没有直接的 is_equality_comparable 类型特征。

    // 编辑:看来我找到了,它是概念特征库中的 ::boost::is_equality_comparable::value: http://neoscientists.org/~tschwinger/boostdev/concept_traits/libs/concept_traits/doc/

    http://neoscientists.org/~tschwinger/boostdev/concept_traits/libs/concept_traits/doc/#StandardConceptTraits

    但是,它似乎被放弃了:https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction#Boost.ConceptTraits

    另一种解决方案是使用 Boost 概念检查库 (BCCL),特别是应用 EqualityComparableConcept:

    http://www.boost.org/doc/libs/release/libs/concept_check/using_concept_check.htm

    另一种选择:Boost.Generic -- https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction#Boost.Generic

    演示文稿:http://github.com/boostcon/2011_presentations/raw/master/thu/Boost.Generic.pdf

    另一种选择: http://code.google.com/p/origin/source/browse/trunk/core/tests/concepts/equality_comparable.cpp

    【讨论】:

    【解决方案3】:

    这现在可以在 C++20 概念库中实现。

    class Node<T> requires Compare<T> {...}
    

    虽然如果不满足概念,这仍然会引发错误,但它更容易理解导致错误的原因。你可以在它周围写一个包装器来防止错误。

    【讨论】:

      【解决方案4】:

      如果您的模板类使用您提到的运算符,如果模板类型参数不支持此类运算符,编译器将发出错误。

      【讨论】:

        【解决方案5】:

        您可以使用 std::less、std::greater 和 std::equal_to。通过在您自己的代码中使用这些函数,您可以确保您的类型 T 实现了这些方法(扩展 Comparable 的种类)。如果你的类型没有这样的方法,你会得到一个编译错误。

        检查this reference 以查看使用示例

        【讨论】:

        • 调用 std::less 并不能确保仅调用 'a
        • std::less 为所有类型声明,即使 std::less::operator() 的定义将无法编译。
        猜你喜欢
        • 2019-03-23
        • 2020-05-08
        • 2014-10-08
        • 2021-12-29
        • 1970-01-01
        • 2018-02-09
        • 2011-03-04
        • 2015-12-12
        • 1970-01-01
        相关资源
        最近更新 更多