C++ determine if class is comparable

人走茶凉 提交于 2019-12-08 15:24:17

问题


I'm more or less Java programmer, so this might be a stupid question, but I didn't manage to find any simple solution.

I have a class like this in C++:

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

And I need T to be comparable - to have at least == < > operators defined. Is there any simple way to do this - or what is the best practice for this? In Java, it would be something like this:

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

Thanks for your help!


回答1:


C++ templates are duck-typed, so no interface or constraint is necessary, the compiler will use the comparison operators if they exist, and generate an error if not.

See also this more detailed answer.




回答2:


If you want to avoid cryptic errors (as you often get when the lack of comparability occurred deeply in the template instantiation tree), just use enable_if:

  • If you have C++98 or C++03 compiler, boost::enable_if: http://www.boost.org/doc/libs/release/libs/utility/enable_if.html

  • If you have C++11 compiler, std::enable_if: http://en.cppreference.com/w/cpp/types/enable_if

In particular, take a look at "Enabling template class specializations" in the docs of boost::enable_if.

You often use enable_if with type_traits: http://www.boost.org/doc/libs/release/libs/type_traits/doc/html/index.html

Of particular interest in your case might be the following ones:

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

But see also has_greater, has_greater_equal, has_less, has_less_equal, etc. // I'm actually somewhat surprised that there isn't a straightforward is_equality_comparable type-trait.

// EDIT: it appears I've found it, it's ::boost::is_equality_comparable::value in the Concept Traits Library: http://neoscientists.org/~tschwinger/boostdev/concept_traits/libs/concept_traits/doc/

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

However, it appears to be abandoned: https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction#Boost.ConceptTraits

An alternative solution is to use the Boost Concept Checking Library (BCCL), in particular applying the EqualityComparableConcept:

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

Yet another alternative: Boost.Generic -- https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction#Boost.Generic

Prensentation: http://github.com/boostcon/2011_presentations/raw/master/thu/Boost.Generic.pdf

Yet another alternative: http://code.google.com/p/origin/source/browse/trunk/core/tests/concepts/equality_comparable.cpp




回答3:


If your template class makes use of the operators you mentioned, the compiler will emit errors if the template type argument doesn't support such operators.




回答4:


You can use std::less, std::greater and std::equal_to. By using those functions in your own code you ensure that your type T has those methods implemented (kind of extends Comparable). If your type has no such methods you will get a compilation error.

Check this reference in order to see an usage example



来源:https://stackoverflow.com/questions/8838800/c-determine-if-class-is-comparable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!