Kann ich herausbekommen, warum ein Template _nicht_ instanziiert wurde?



  • Ich habe einen Anwendungsfall, in dem abgeleitete Klassen eine Templatefunktion der Basisklasse benutzen sollen, die wiederum eine in den abgeleiteten Klassen implementierte virtuelle Funktion aufruft. Beispiel:

    #include <iostream>
      
    using std::cout;
    using std::endl;
    
    class Base {
    public:
      virtual void func_individuell() = 0;
      template<typename... Args>
      void func_gemeinsam(Args&&... args) {
        func_individuell();
        cout << "Yeah." << endl;
      }
    };
    
    class Derived : public Base {
    public:
      void func_individuell() {
        cout << " - Derived - " << endl;
      }
    };
    
    class Derived2 : public Base {
    public:
      void func_individuell() {
        cout << " - Derived 2 - " << endl;
      }
    };
    
    int main(int argc, char **argv) {
      Derived instanz;
      Derived2 instanz2;
    
      instanz.func_gemeinsam("xxx");
      instanz2.func_gemeinsam(1, "xxx");
    
      return 0;
    }
    

    Das klappt soweit auch - dieses kleine Beispiel.

    In der realen Anwendung sind die Klassen sehr viel komplexer, aber das Grundprinzip ist gleich, vor allem ist die virtuelle Funktion genau so wie im Beispiel implementiert.

    Leider klappt es damit nicht genauso; wenn ich die Templatefunktion in der Basisklasse habe, kann der Compiler sie aus einem mir noch unbekannten Grund nicht instanziieren, er findet keine passende Signatur.

    Schiebe ich die Templatefunktion in die abgeleiteten Klassen, klappt es.

    Es muss also irgendwas in der Templatefunktion für den Compiler unsichtbar sein, wenn sie in der Basisklasse steht, das verfügbar wird, wenn die Templatefunktion in der abgeleiteten Klasse instanziiert wird.

    Deswegen meine Frage: kann man den Compiler (g++ in meinem Fall) dazu bringen, sich ausführlich über den Instanziierungsprozess der Templatefunktionen auszulassen?



  • @Miq sagte in Kann ich herausbekommen, warum ein Template _nicht_ instanziiert wurde?:

    Leider klappt es damit nicht genauso; wenn ich die Templatefunktion in der Basisklasse habe, kann der Compiler sie aus einem mir noch unbekannten Grund nicht instanziieren, er findet keine passende Signatur.

    Gibts das auch als direktes Zitat statt als Erinnerungsprotokoll der Meldung?
    Doofe Frage: das template ist aber in der Header-Datei drin und nicht in der cpp-Datei?



  • @Miq sagte in Kann ich herausbekommen, warum ein Template _nicht_ instanziiert wurde?:

    Deswegen meine Frage: kann man den Compiler (g++ in meinem Fall) dazu bringen, sich ausführlich über den Instanziierungsprozess der Templatefunktionen auszulassen?

    https://gcc.gnu.org/wiki/ClangDiagnosticsComparison



  • Ja, gibt es, aber ich habe die Lösung inzwischen gefunden 😁

    Ich hatte die virtuelle Funktion genauso genannt wie die Templatefunktion - in der Hoffnung, dass die eindeutige Funktionssignatur dem Compiler die Entscheidung erlaubt. Dem ist wohl nicht so; sobald ich die virtuelle Funktion anders genannt hatte als die Templatefunktion, compiliert es ohne Fehler.



  • @Miq
    Namen in abgeleiteten Klassen "verdecken" identische Namen der Basisklasse.
    Das passiert nicht nur mit Template-Funktionen sondern generell.
    Also das geht so nicht:

    struct Base {
        void fun(int i);
    };
    
    struct Derived : Base {
        void fun();
    };
    
    int main() {
        Derived d;
        d.fun(123); // nope
    }
    

    Wenn du willst dass es geht, kannst du using verwenden:

    struct Base {
        void fun(int i);
    };
    
    struct Derived : Base {
        using Base::fun; // <-----------------
        void fun();
    };
    
    int main() {
        Derived d;
        d.fun(123); // OK
    }