Funktion in Klassentemplate spezialisieren



  • hallo,
    ich habe ein Problem um komme gerade nicht weiter, folgendes:
    Ich habe ein Klassentemplate (K), in diesem befindet sich eine Funktion (int fkt(..);).
    Da für die verschiedenen Ausprägungen der Klasse die Funktion unterschiedliche Berechnungen durchführen soll, will ich sie Spezialisieren.

    Ich habe nun folgende Möglichkeiten bis jetzt gefunden, die mir aber alle nicht so ganz gefallen:

    1. Abgeleitetes Klasse von K, die die Funktion enthält und dann entsprechend spezialisiert ist. Das ist aber schlecht, weil ich dann einen Haufen Klassen schreiben und einbinden muß.

    2. Klasse mit der templatetisierten Funktion fkt, die Zugriff von Klasse K erlaubt (Stichwort friend). Allerdings müßte ich dann extra eine Klasse instanzieren, die nichts weiter macht, als die Funktion in ihrer bestimmten Ausprägung bereitzustellen.

    Hat jemand schon Erfahrunge mit diesem Problem und vielleicht eine elegante Lösung? Die Diskussion sei eröffnet... 🤡



  • Hallo,
    was ist mit der naheliegensten Variante?

    template <class T>
    class Foo {
    public:
        int f();
    };
    
    template <class T>
    int Foo<T>::f() {
        // Default-Impl
    }
    
    template <>
    int Foo<int>::f() {
        // Spezialisierung von f für Foo<int>
    
    }
    
    template <>
    int Foo<double>::f() {
        // Spezialisierung von f für Foo<double>
    }
    

    Das geht natürlich nur, wenn die Spezialisierungen alle vollständig sind.

    Falls du partielle Spezialisierungen brauchst, würde ich mich zuerst fragen, ob das Design wirklich so sinnvoll ist. Vielleicht gehört die Funktion besser nicht in das Template? Lohnt es sich wirklich, dass K ein Template ist?
    Falls du dann immer noch partielle Spezialisierungen deiner Funktion haben willst, hilft eine Indirektion. Z.B. so:

    template <class T, class U>
    class Foo {
    public:
        int f();
        int f_1(); // Allgemeine Impl
        int f_2(); // Impl für Foo<T*, U>
        int f_3(); // Impl für Foo<T, U*>
    };
    
    template <class T, class U>
    struct Selector {
        static int f( Foo<T, U>* foo ) {
            return foo->f_1();
        }
    };
    
    template <class T, class U>
    int Foo<T, U>::f() {
        return Selector<T, U>::f(this);
    }
    
    template <class T, class U>
    struct Selector<T*, U> {
        static int f( Foo<T*, U>* foo ) {
            return foo->f_2();
        }
    };
    template <class T, class U>
    struct Selector<T, U*> {
        static int f( Foo<T, U*>* foo ) {
            return foo->f_3();
        }
    };
    

Log in to reply