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!
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.
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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With