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 von a abgeleitete Typen, der nur so eine Helper-Klasse zurückgibt.


  • Mod

    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.


  • Mod

    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) von a 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. 🙂


Anmelden zum Antworten