Также можно использовать только черты типа c ++ 11 для проверки существования члена:
#include <type_traits>
#include <utility>
template<class T, class EqualTo>
struct has_operator_equal_impl
{
template<class U, class V>
static auto test(U*) -> decltype(std::declval<U>() == std::declval<V>());
template<typename, typename>
static auto test(...) -> std::false_type;
using type = typename std::is_same<bool, decltype(test<T, EqualTo>(0))>::type;
};
template<class T, class EqualTo = T>
struct has_operator_equal : has_operator_equal_impl<T, EqualTo>::type {};
Вы можете использовать эту черту следующим образом:
bool test = has_operator_equal<MyClass>::value;
Результирующий тип has_operator_equal
будет либо std::true_type
, либо std::false_type
(поскольку он наследуется от псевдонима std::is_same::type
), и оба определяют статический член value
, который является логическое значение.
Если вы хотите проверить, определяет ли ваш класс operator==(someOtherType)
, вы можете установить второй аргумент шаблона:
bool test = has_operator_equal<MyClass, long>::value;
, где параметр шаблона MyClass
по-прежнему является классом, который вы тестируете на наличие operator==
, а long
- это тип, с которым вы хотите иметь возможность сравнивать, например, чтобы проверить, что MyClass
имеет operator==(long)
.
, если EqualTo
(как это было в первом примере) оставить неуказанным, по умолчанию будет T
, результатом будет обычное определение operator==(MyClass)
.
Примечание предостережения : эта черта в случае operator==(long)
будет верна для long
или для любого значения, неявно преобразуемого в long
, например. double
, int
и т. Д.
Вы также можете определить проверки для других операторов и функций, просто заменив то, что находится внутри decltype
. Чтобы проверить !=
, просто замените
static auto test(U*) -> decltype(std::declval<U>() == std::declval<V>());
* * С тысячей сорок-девять
static auto test(U*) -> decltype(std::declval<U>() != std::declval<V>());