С++ определяет, сопоставим ли класс

Я более или менее Java-программист, так что это может быть глупый вопрос, но мне не удалось найти простого решения.

У меня есть такой класс на С++:

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

И мне нужно, чтобы T был сопоставим - чтобы были определены хотя бы == ‹ > операторы. Есть ли какой-нибудь простой способ сделать это или как лучше всего это сделать? В Java это будет примерно так:

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

Спасибо за вашу помощь!


person Jaa-c    schedule 12.01.2012    source источник
comment
Node это не класс, это шаблон класса.   -  person ildjarn    schedule 12.01.2012
comment
Возможно, связано: Обнаружение поддержки оператора с помощью decltype/SFINAE   -  person ildjarn    schedule 12.01.2012


Ответы (5)


Шаблоны C++ имеют утиную типизацию, поэтому интерфейс или ограничение не требуются, компилятор будет использовать операторы сравнения, если они существуют, и сгенерировать ошибку, если нет.

См. также этот более подробный ответ.

person Ben Voigt    schedule 12.01.2012

Если вы хотите избежать загадочных ошибок (что часто случается, когда несопоставимость возникает глубоко в дереве экземпляров шаблона), просто используйте enable_if:

В частности, взгляните на «Включение специализаций классов шаблонов» в документации boost::enable_if.

Вы часто используете enable_if с type_traits: http://www.boost.org/doc/libs/release/libs/type_traits/doc/html/index.html

Особый интерес в вашем случае могут представлять следующие:

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

Но см. также has_greater, has_greater_equal, has_less, has_less_equal и т. д. // На самом деле я несколько удивлен, что нет прямой черты типа is_equality_comparable.

// РЕДАКТИРОВАТЬ: кажется, я нашел его, это ::boost::is_equality_comparable::value в библиотеке черт концептов: http://neoscientists.org/~tschwinger/boostdev/concept_traits/libs/concept_traits/doc/

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

Однако похоже, что он заброшен: https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction#Boost.ConceptTraits

Альтернативным решением является использование библиотеки проверки концепций Boost (BCCL), в частности применение EqualityComparableConcept:

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

Еще одна альтернатива: Boost.Generic -- https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction#Boost.Generic

Презентация: http://github.com/boostcon/2011_presentations/raw/master/thu/Boost.Generic.pdf

Еще одна альтернатива: http://code.google.com/p/origin/source/browse/trunk/core/tests/concepts/equality_comparable.cpp

person Matt    schedule 13.01.2012
comment
Вы также можете взглянуть на следующее: comments.gmane.org/ gmane.comp.lib.boost.devel/223294 мартинекер .com/вики/ - person Matt; 14.01.2012

Если ваш класс шаблона использует упомянутые вами операторы, компилятор выдаст ошибки, если аргумент типа шаблона не поддерживает такие операторы.

person Bukes    schedule 12.01.2012

Теперь это возможно в библиотеке C++20 Concepts.

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

Хотя это все равно вызовет ошибку, если концепция не будет удовлетворена, это упрощает понимание того, что вызвало ошибку. Вы можете написать обертку вокруг него, чтобы предотвратить ошибки.

person Aniket Chowdhury    schedule 11.04.2020

Вы можете использовать std::less, std::greater и std::equal_to. Используя эти функции в своем собственном коде, вы гарантируете, что в вашем типе T реализованы эти методы (вроде расширения Comparable). Если ваш тип не имеет таких методов, вы получите ошибку компиляции.

Проверьте эту ссылку, чтобы увидеть пример использования

person tonicebrian    schedule 12.01.2012
comment
вызов std::less не гарантирует ничего, что делает простой вызов 'a‹b'. - person Mooing Duck; 14.01.2012
comment
std::less объявлен для всех типов, даже если определение std::less::operator() не скомпилируется. - person Daniel Stutzbach; 22.07.2018