2016-02-15 18 views
12

Bir sınıfın operator== yöntemine sahip olup olmadığını kontrol etmeye çalışıyorum. SFINAE here ile bir çözüm buldum ve yaptığım sınıfla iyi çalışıyor. Ben çalıştığınızda,, bir işleç sahibi var ==

template <typename T> 
class comparable 
{ 
    typedef char one; 
    typedef long two; 

    template <typename C> static one test(typeof(&C::operator==)) ; 
    template <typename C> static two test(...); 


public: 
    enum { value = sizeof(test<T>(0)) == sizeof(char) }; 
}; 

Ama:

Bu şuna benzer

std::cout << comparable<int>::value << std::endl; 

Ben gerçek döndürecek şekilde bekliyordum ederken Sonra yanlış döndürür. Bu neden ?

+1

Eğer düzenlemek (üç nokta ne anlama) önce orada vardı soruya Hakkında bakmak Bu soru: http://stackoverflow.com/questions/1657883/variable-number-of-arguments-in-c – Anedar

+1

Sınıf C {...}; bool operatörü == (const C & a, const C & b) {...} '? Kodunuz, operatörde == olduğunu, çünkü sınıfta biri olmadığını söyleyecektir. – immibis

cevap

19

int sınıf içi ve operator== numaralı üyeye sahip değildir, &C::operator== numaralı telefon numaranızla, sizin kontrolünüzle uyumludur. Böylece, test "hayır" verir. Başkalarının doğru bir şekilde işaret ettiği gibi, testiniz de yalnızca üye olmayan operator== olan sınıflar için negatif olacaktır. ifadesi C==C geçerli olup olmadığını How to check whether operator== exists?

+3

Dupe aslında ?? –

+1

@ πάνταῥεῖ Ona yaklaşımının neden başarısız olduğunu anlatmıyor, en azından Mjölnir'i yapmayacağım. Ama katılıyorum, bu kolay bir 80 temsilcisi oldu. –

+1

Odin’in oğullarıyız ve güçlerimizin sorumlu kullanıcıları olmalıyız. İyi hazırlanmış ve +80 için tebrikler (bir 10 benim tarafımdan). –

4

Testiniz test etmez:

Nasıl doğru bir operator== burada istendi Varlığından olmadığını kontrol etmek. Sınıfınız C'un C::operator== sürümüne sahip olup olmadığını sınar. int sınıfından beri sınıf üyesi yok.

Test yapmayı deneyin örn. typeof(C()==C())

10

Anında yaklaşımınız en az iki temel nedenden ötürü hatalı (veya eksik) durumdadır. C bir üyeye sahiptir Öncelikle

, senin yöntem çekleri sınıf olmadığını operator == adını verdi. Sınıf dışı türler bu testi geçemez, çünkü hiçbir üyesi yoktur. Ve int, sınıf dışı bir türüdür. İkinci olarak, bu yaklaşım kendi başına operator =='un bağımsız bir işlev olarak uygulandığı sınıfları tespit etmemektedir. Örneğin, testiniz std::string'un == operatörüne sahip olmadığını söyleyecektir. std::string'un böyle bir üyeye sahip olmadığı doğrudur, ancak'un eşitliğini bağımsız operator == kullanarak karşılaştırabilirsiniz. Yani, int bir şekilde bir sınıf tipi olsa bile, hala bir üye işlevi olarak operator == uygulayacağı anlamına gelmez. Eğer ++ 11 c kullanırsanız

0

Eğer uygulanmasını çok daha kolay hale getirecek olan decltype kullanabilirsiniz:

#include <iostream> 
#include <type_traits> 

using namespace std; 

template <class T, class Sfinae = void> 
class comparable { 
public: 
    static constexpr bool value = false; 
}; 

template <class T> 
class comparable <T, typename enable_if<is_same<decltype(declval<T>() == declval<T>()), bool>::value>::type> { 
public: 
    static constexpr bool value = true; 
}; 

class A { 
public: 
    bool operator==(const A &) { 
     return true; 
    } 
}; 

class B { 
}; 

int main() { 
    cout << comparable<int>::value << endl; // output: 1 
    cout << comparable<A>::value << endl; // output: 1 
    cout << comparable<B>::value << endl; // output: 0 
}