Template-Methode in Klasse nicht verfügbar: "no matching function for call to"
-
Ja, bringt er. Natürlich ist mein Minimal-Test-Code etwas umfangreicher als der gepostete.
-
Deine Klasse hat ja auch keine Memberfunktion namens getConcreteMember(). Deine Klasse hat ein Funktionstemplate mit diesem Namen, aber woher soll der Compiler wissen, wie er es spezialisieren soll? Das musst du ihm schon irgendwo sagen.
edit: Deine Beschreibung hört sich irgendwie komisch an. Suchst du vielleicht virtuelle Methoden und Polymorphie? Was soll denn dein Design bezwecken?
-
SeppJ schrieb:
Deine Klasse hat ja auch keine Memberfunktion namens getConcreteMember(). Deine Klasse hat ein Funktionstemplate mit diesem Namen, aber woher soll der Compiler wissen, wie er es spezialisieren soll? Das musst du ihm schon irgendwo sagen.
Du meinst die Implementierung in der Header-Datei? Ich formulier mal ein kleines Bsp. aus:
// ebenfalls in der Headerdatei: template <typename T> T* BaseChnA::getConcreteMember() { /* Implementierung der Template-Funktion */ if(...) return dynamic_cast<ConcreteMember1*>(m_member); else return dynamic_cast<ConcreteMember2*>(m_member); }Reicht das dem Compiler nicht um die Fkt zu kompilieren?
Erst mit dem genauen Typ kann ich dann eine Funktion aufrufen, die nicht in der Basisklasse vorkommt. Das sollte imho dann so aussehen:
getConcreteMember()->doSthSpecial1();Ich muss mich natürlich selbst drum kümmern dass der Cast funktioniert bzw. den Cast vorher überprüfen.
SeppJ schrieb:
edit: Deine Beschreibung hört sich irgendwie komisch an. Suchst du vielleicht virtuelle Methoden und Polymorphie? Was soll denn dein Design bezwecken?
Ja, da hast Du leider Recht. Ist auch keine schöne Lösung sondern ein Workaround, um bereits begangene Fehler ein wenig auszubessern und wurde bereits diskutiert:
http://www.c-plusplus.net/forum/viewtopic-var-p-is-1803156.html#1803156
-
Radix schrieb:
Ja, bringt er. Natürlich ist mein Minimal-Test-Code etwas umfangreicher als der gepostete.
In solchen Fällen sollte auch der gepostete Code in (ansonsten) compilierbaren Zustand sein, um den Fehler eindeutig identifizieren zu können. Schließlich kann ich auf Anhieb mehrere Fehler nennen, die Compiler hier anmerken würde, schlicht deshalb, weil das Beispiel unvollständig ist. Im Ergebnis schaue ich mir den Code so gar nicht an.
Im Übrigen ist BaseChnA::getConcreteMember ein Template, bei dem der jeweilige Templateparameter nicht deduziert werden kann und folglich explizit angegeben werden muss.
-
camper schrieb:
In solchen Fällen sollte auch der gepostete Code in (ansonsten) compilierbaren Zustand sein, um den Fehler eindeutig identifizieren zu können. Schließlich kann ich auf Anhieb mehrere Fehler nennen, die Compiler hier anmerken würde, schlicht deshalb, weil das Beispiel unvollständig ist. Im Ergebnis schaue ich mir den Code so gar nicht an.
Ich dachte dass man an meinem Bsp mit den relevanten Code-Bestandteilen einen prinzipiellen Fehler erkennen kann und dass der komplette Code (umfasst ja immerhin 6 Klassen) die Sache in diesem Fall schwieriger gestaltet.
camper schrieb:
Im Übrigen ist BaseChnA::getConcreteMember ein Template, bei dem der jeweilige Templateparameter nicht deduziert werden kann und folglich explizit angegeben werden muss.
Okay, das hab ich jetzt nicht ganz verstanden. Heißt das, dass der tatsächlich zurückzugebende Typ der Funktion bereits beim Aufruf bekannt sein muss, also bspw. ein Objekt des selben Typs als Parameter übergeben werden müsste?
-
getConcreteMember<ConcreteMember1>()->doSthSpecial1();
-
Ja genau, oder soll der Compiler raten?
-
Radix schrieb:
der komplette Code (umfasst ja immerhin 6 Klassen)
Das ist aber nicht sooo viel, und sollte kein Hinderungsgrund sein, dein Design nochmal zu überdenken. Denn wenn du für jedes neue Feature, das sich durch besseres Design schön einfügen ließe einen weiteren Hack einbauen musst, hast du demnächst absolut unwartbaren Code, der sowieso neu designed werden muss, und dann dauerts richtig lange!
-
lego_123 schrieb:
Radix schrieb:
der komplette Code (umfasst ja immerhin 6 Klassen)
Das ist aber nicht sooo viel, und sollte kein Hinderungsgrund sein, dein Design nochmal zu überdenken. Denn wenn du für jedes neue Feature, das sich durch besseres Design schön einfügen ließe einen weiteren Hack einbauen musst, hast du demnächst absolut unwartbaren Code, der sowieso neu designed werden muss, und dann dauerts richtig lange!
Mit den 6 Klassen meinte ich nur meinen Testcode, das richtige Programm hat 'ne andere Größenordnung...
Th69 schrieb:
Ja genau, oder soll der Compiler raten?
Ich hab irgendwie damit gerechnet dass das zur Laufzeit bewerkstelligt werden kann. Okay, ist bei Template-Funktionen also nicht der Fall und die Lösung muss damit anders aussehen.
Ich müsste bspw. die Fallunterscheidung - falls eine nötig ist (und das ist glücklicherweise nicht bei vielen Channel-Klassen der Fall) - in die Channel-Klasse verlegen.
-
Radix schrieb:
Th69 schrieb:
Ja genau, oder soll der Compiler raten?
Ich hab irgendwie damit gerechnet dass das zur Laufzeit bewerkstelligt werden kann.
Template != Runtime!!!
Templates werden zur Compiletime ausgewertet und in Code gegossen. Jede Template-Funktion/Klasse bekommt für eine andere Zusammensetzung der template-Parameter eigenen Code generiert und kompiliert.