2015-10-17 10 views
6

Bir "is_comparable" typetrait arıyorum ama bulamıyorum.Aradığınız "is_comparable" typetrait

Bir sınıf için bir operator== uygulanıp uygulanmadığını denetleyen bir tane oluşturmak çok kolaydır, ancak bu genel tanımlı işleçleri hariç tutar.

Bir is_comparable typetait uygulamak imkansız mı?

cevap

3

Sana lhs == rhs aksi false derleyip olacak true eğer iki tip L ve R ve nesneler lhs ve sırasıyla bu türde rhs için verecektir, bir özelliği anlamına götürün. numaralı kuralı olan numaralı kuralı, rhs == lhs veya lhs != rhs,yapmıyor olsa bile, derlemeniz için teşekkür ederiz. Eğer böyle bir özellik uygulamak olabilir Bu durumda

:

#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{}; 

Bu this question

cevap olarak açıklanmıştır özellikleri tanımlamak için popüler bir SFINAE deseni Bazı çizimler geçerlidir:

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,""); 

Eşitliğin simetrik olmasını ve bu eşitsizliğin olmasını gerektiren özelliği istiyorsanız da var ve simetrik, kendinizi nasıl detaylandıracağınızı görebiliyorsunuz.

+0

Cevabınız için teşekkürler, ancak çalışmıyor. Bu kodu gcc ile derlemeye çalışırken static_assert bile başarısız. Sorun, "std :: declval () == std :: declval ()" olarak değerlendirilmiş gibi görünüyor. İlginç bir şekilde clang-3.8 beklediğim gibi bir derleme istisnası atar. – Gene

+0

@Gene Odd, [gcc 5.2 live] (https://goo.gl/0Le5lw) ve [clang 3.6 live] (https://goo.gl/uLkdnm) ile derledim. Belki de başarısız derlemenizi gönderebilirsiniz? –

+0

İlginç ... Static_assert hakkında da şikayette bulunan gcc 4.9.2'yi kullandım. Benim yerel örneğim de biraz daha karmaşıktı. Sonunda bir çift tanımı ekledim, bu da clang 3.6 canlılığını da unexpectly yapar: https://goo.gl/OKsuIU – Gene

İlgili konular