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
  • 4,967
  • 3
  • 33
  • 63

5 Answers5

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
  • 269,602
  • 39
  • 394
  • 697
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
  • 598
  • 8
  • 19
  • 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
  • 322
  • 2
  • 12
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,638
  • 1
  • 15
  • 20
-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

tonicebrian
  • 4,735
  • 5
  • 39
  • 59