2015-10-17 3 views
6

Я ищу «is_comparable» typetrait, но не могу найти.Ищете «is_comparable» typetrait

Очень легко построить тот, который проверяет, был ли реализован класс operator== для класса, но это исключает глобально определенные операторы.

Невозможно ли реализовать is_comparable typetait?

ответ

3

Я понимаю, что вы имели в виду черта, что для двух типов L и R и объектов lhs и rhs этих типов соответственно, приведет к получению true если lhs == rhs будет компилировать и false иначе. Вы понимаете, что в теории lhs == rhs может скомпилировать хотя бы rhs == lhs, или lhs != rhs, нет.

В этом случае вы могли бы реализовать черты, как:

#include <type_traits> 

template<class ...> using void_t = void; 

template<typename L, typename R, class = void> 
struct is_comparable : std::false_type {}; 

template<typename L, typename R> 
using comparability = decltype(std::declval<L>() == std::declval<R>()); 

template<typename L, typename R> 
struct is_comparable<L,R,void_t<comparability<L,R>>> : std::true_type{}; 

Это относится популярный шаблон SFINAE для определения черты, объясняется в ответ на this question

Некоторые иллюстрации:

struct noncomparable{}; 

struct comparable_right 
{ 
    bool operator==(comparable_right const & other) const { 
     return true; 
    } 
}; 

struct any_comparable_right 
{ 
    template<typename T> 
    bool operator==(T && other) const { 
     return false; 
    } 
}; 

bool operator==(noncomparable const & lhs, int i) { 
    return true; 
} 

#include <string> 

static_assert(is_comparable<comparable_right,comparable_right>::value,""); 
static_assert(!is_comparable<noncomparable,noncomparable>::value,""); 
static_assert(!is_comparable<noncomparable,any_comparable_right>::value,""); 
static_assert(is_comparable<any_comparable_right,noncomparable>::value,""); 
static_assert(is_comparable<noncomparable,int>::value,""); 
static_assert(!is_comparable<int,noncomparable>::value,""); 
static_assert(is_comparable<char *,std::string>::value,""); 
static_assert(!is_comparable<char const *,char>::value,""); 
static_assert(is_comparable<double,char>::value,""); 

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

+0

Thx для вашего ответа, но он не работает. Даже ваш static_assert не работает при попытке скомпилировать этот код с помощью gcc. Кажется, что проблема «std :: declval () == std :: declval ()», которая не получает оценку. Интересно, что clang-3.8 выбрасывает компиляционное исключение, как я ожидал. – Gene

+0

@Gene Odd, он скомпилирован для меня с [gcc 5.2 live] (https://goo.gl/0Le5lw) и [clang 3.6 live] (https://goo.gl/uLkdnm). Возможно, вы могли бы опубликовать свой компромисс? –

+0

Интересно ... Я использовал gcc 4.9.2, который также жалуется на static_assert. Мой местный пример также был немного сложнее. Я добавил определение пары в конце, что делает clang 3.6 live также непредсказуемым: https://goo.gl/OKsuIU – Gene

 Смежные вопросы

  • Нет связанных вопросов^_^