2013-06-23 19 views
7

Mam klasy szablonu zdefiniowanego jak tenOperator przeciążenie poza klasą szablonu z niejawne konwersje

template<class T> class Wrap 
{ 
    /* ... */ 
public: 
    Wrap(const T&); 
    /* other implicit conversions */ 

    /* ... */ 
}; 

chcę definiować wszystkich operatorów porównania dla tej klasy poza klasy jak ten

template<typename T> bool operator == (const Wrap<T>&, const Wrap<T>&) 
{ 
    // Do comparison here 
} 

Ta deklaracja nie obsługuje jednak niejawnych konwersji const T& ani żadnego innego typu na const Wrap<T>&.

Moje pytanie brzmi: w jaki sposób sprawić, aby wspierał on niejawne konwersje, gdy jeden z argumentów jest typu Wrap<T>, a drugi nie. Nie chcę pisać wielu deklaracji każdego operatora dla każdej możliwej permutacji.

Odpowiedz

4
template<class T> struct is_wrap : std::false_type {}; 
template<class T> struct is_wrap<Wrap<T>> : std::true_type {}; 

template<class T1, class T2> typename std::enable_if<is_wrap<typename std::common_type<T1, T2>::type>::value, bool>::type operator == (const T1& t1, const T2& t2) 
{ 
    const typename std::common_type<T1, T2>::type& tc1 = t1, tc2 = t2; 
    // compare with tc1 and tc2 
} 
+0

Świetna odpowiedź. Domyślam się, że brakowało ci odwołania do "tc2". – user1353535

1

Ktoś inny będzie to artykułować lepiej, ale myślę, że problemem jest to, że kompilator nie może wydedukować T w Wrap<T> bez podania go przez obiekt Wrap. Myślę, że twoja sytuacja powinna zostać rozwiązana, jeśli jawnie podasz operator== argument szablonu: operator==<int>(7, 4), na przykład powinien zadziałać.

nie mam kompilatora przede mną, ale tutaj jest mój próba:

template<typename T> 
typename std::enable_if<std::is_convertible<Wrap<T>, T>::value, bool>::type operator==(const Wrap<T>& l, const T& r) 
{ 
    return l.stuff == Wrap<T>(r).stuff; 
} 

template<typename T> 
typename std::enable_if<std::is_convertible<Wrap<T>, T>::value, bool>::type operator==(const T& l, const Wrap<T>& r) 
{ 
    return r == l; // call above operator 
} 

To powinno działać, jeśli po obu stronach jest Wrap a druga strona nie jest. Można również zrobić obie strony jako const T& jednak jeśli Wrap jest naprawdę niejawnie constructible z dowolnego T będzie można skończyć za pomocą swojego operator== wielu niezamierzonych porównań, nawet int s, string s itd

+0

ta nadal wymaga do dodania 2 innych deklaracji dla każdego operatora, których chciałem uniknąć. – user1353535

Powiązane problemy