13

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!

Jaa-c
  • 5,017
  • 4
  • 34
  • 64

4 Answers4

15

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.

Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
5

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:

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

Matt
  • 629
  • 9
  • 21
  • You might also take a look at the following: http://comments.gmane.org/gmane.comp.lib.boost.devel/223294 http://www.martinecker.com/wiki/index.php?title=Detecting_the_Existence_of_Operators_at_Compile-Time – Matt Jan 14 '12 at 18:45
3

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.

Aniket Chowdhury
  • 332
  • 3
  • 13
2

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.

Bukes
  • 3,668
  • 1
  • 18
  • 20