SFINAE, hier in Ordnung?
-
Ich hab ein paar Klassen, die zueinander statisch polymorph sind und möchte nun Operatoren zwischen allen abgeleiteten Klassen definieren. Mein Ansatz sieht etwa so aus:
struct a{}; //Die Basisklasse aller Klassen in dieser Hierarchie; vom Template-Typen unabhängig; macht nichts besonderes, sondern dient lediglich der Identifikation template<typename T> struct b : a{}; //Hier sind je nach Typ T Dinge drin, die für die abgeleiteten Klassen interessant sind template<typename T> struct c : b<T>{}; template<typename T> struct d : b<T>{}; //Gibt noch 'ne Menge mehr, hier einfach mal exemplarisch zwei Stück template<typename L, typename R> struct add_helper { L l; R r; add_helper(const L &l, const R &r) : l(l), r(r) {} //Schlussendlich stecken hier dann einige interessante Dinge drin, die mit l und r operieren }; template<typename L, typename R, typename = typename std::enable_if<std::is_base_of<a, L>::value && std::is_base_of<a, R>::value>::type> add_helper<L, R> operator+ (const L &l, const R &r) { return add_helper<L, R>(l, r); } int main() { some_l33t_func(c<int>(...) + d<float>(...)); }
Kann das Konflikte geben mit anderen überladenen Operatoren? Wie würdet ihr sowas machen? Das Ziel ist es nur, dass ich einen
operator$
habe für beliebige vona
abgeleitete Typen, der nur so eine Helper-Klasse zurückgibt.
-
Das sieht isoliert aus.
Für das enable_if-Argument empfehle ich allerdings allgemain ein non-type Argument, z.B.template<typename L, typename R, typename std::enable_if<std::is_base_of<a, L>::value && std::is_base_of<a, R>::value, int>::type = 0> add_helper<L, R> operator+ (const L &l, const R &r) { return add_helper<L, R>(l, r); }
Auf diese Weise ist die Bedingung teil der Signatur des Templates, so dass es keine Probleme bereit, den operator noch anderweitig mit einer anderen Bedingung zu überladen.
-
Kann das Konflikte geben mit anderen überladenen Operatoren?
Das kann nur Konflikte mit anderen überladenen Operatoren ergeben, wenn du diese so auslegst, dass sie auch auf von
a
abgeleitete Klassen operieren. Ist einer der beiden Operanden nämlich nicht (sichtbar) vona
abgeleitet, wird die Spezialisierung gar nicht zum Candidate Set hinzugefügt.Edit: Frage hat sich geklärt.
-
Alles klar, danke euch beiden. Mann, wie ich hacken in C++ liebe.