Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ determine if class is comparable

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!

like image 590
Jaa-c Avatar asked Jan 12 '12 16:01

Jaa-c


4 Answers

This is now possible in C++20 Concepts library.

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

Though this will still throw an error if the concept is not satisfied, it makes it easier to understand what caused the error. You can write a wrapper around it to prevent errors.

like image 77
Aniket Chowdhury Avatar answered Sep 22 '22 01:09

Aniket Chowdhury


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.

like image 21
Ben Voigt Avatar answered Sep 22 '22 01:09

Ben Voigt


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

like image 29
Matt Avatar answered Sep 21 '22 01:09

Matt


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.

like image 2
Bukes Avatar answered Sep 24 '22 01:09

Bukes