2013-06-23 9 views
7

ich eine Template-Klasse wie diese außerhalb der KlasseBetreiber Überlastung außerhalb einer Template-Klasse mit impliziten Konvertierungen

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

    /* ... */ 
}; 

Ich möchte für diese Klasse die Vergleichsoperatoren alle definieren, wie diese

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

definiert haben Diese Deklaration unterstützt jedoch keine impliziten Konvertierungen von const T& oder einem anderen Typ zu const Wrap<T>&.

Also meine Frage ist, wie kann ich es unterstützen implizite Konvertierungen, wenn einer der Operanden vom Typ Wrap<T> ist und der andere nicht. Ich möchte nicht mehrere Deklarationen jedes Operators für jede mögliche Permutation schreiben.

Antwort

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

Große Antwort. Ich nehme an, dass Sie die Referenz für "tc2" nicht gefunden haben. – user1353535

1

Jemand anders wird dies besser artikulieren, aber ich denke, das Problem ist, dass der Compiler T in Wrap<T> ohne Sie kein Wrap Objekt übergeben kann. Ich denke, deine Situation sollte gelöst werden, wenn du dem operator== ein Template-Argument explizit gibst: operator==<int>(7, 4), sollte zum Beispiel funktionieren.

Ich habe keinen Compiler vor mir habe, aber hier ist mein Versuch:

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 
} 

Dies sollte funktionieren, wenn auf beiden Seiten ein Wrap und die andere Seite nicht. Sie tun können auch beide Seiten als const T&, aber wenn Wrap wirklich von jedem T implizit konstruierbar ist, werden Sie Ihre operator== für viele unbeabsichtigte Vergleiche aufzuwickeln Verwendung auch von int s, string s usw.

+0

Dies erfordert nach wie vor mir zwei weitere Deklarationen für jeden Operator hinzuzufügen, die ich vermeiden wollte. – user1353535

Verwandte Themen