Fehler, Code -> Source File, Klassentemplate
-
Hi,
ich habe ein Klassentemplate (das sich im Namespace
Node
befindet)template<class N, class C, class IC, class T> class Base_Nd { ... class Site_Cntr; boost::shared_ptr<Site_Cntr> site_cntr() const { return m_site_cntr; }; boost::shared_ptr<Site_Cntr> m_site_cntr; }
Die Methode
site_cntr
würde ich nun gerne in die zugehörige Source-Datei verschieben. Wenn ich aberboost::shared_ptr<Site_Cntr> site_cntr() const { return m_site_cntr; };
durch
boost::shared_ptr<Site_Cntr> site_cntr() const;
ersetze und
template<class N, class C, class IC, class T> boost::shared_ptr< Node::Base_Nd<N, C, IC, T>::Site_Cntr > Node::Base_Nd<N, C, IC, T>::site_cntr() const { return m_site_cntr; }
in der Source-Datei hinzufüge, bekomme ich die Fehlermeldung
In file included from ../src/node/base_nd.cpp:3: ../src/node/base_nd_def.h:187: error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> class boost::shared_ptr’ ../src/node/base_nd_def.h:187: error: expected a type, got ‘Node::Base_Nd ::Site_Cntr’ ../src/node/base_nd_def.h:187: error: prototype for ‘int Node::Base_Nd< N, C, IC, T>::site_cntr() const’ does not match any in class ‘Node ::Base_Nd<N, C, IC, T>’ ../src/node/base_nd.h:134: error: candidate is: boost::shared_ptr< Node::Base_Nd<N, C, IC, T>::Site_Cntr> Node::Base_Nd<N, C, IC, T> ::site_cntr() const
Kann mir jemand sagen, was ich hier falsch mache? Ich verstehe insbesondere nicht, warum der Compiler meint,
Node::Base_Nd::Site_Cntr
sei kein Typ.
-
Das Vorhaben ist von vornherein verdammt, da du Definitionen von Templates an der Stelle vorliegen müssen, wo sie instanziert werden ~(oder genauer: Sie müssen mindestens einmal vorgelegen haben, wenn eine spezielle Instanz erzeugt werden soll)~. Üblicherweise geht das nur, wenn die Definition in einem Header steht ~(außer du instanzierst alles was du brauchst explizit in der Sourcedatei, womit aber irgendwie der Sinn von Templates futsch wäre)~.
Die kleingeschriebenen Passagen kannst du ignorieren, die sind nur da, um die Klugscheißer ruhig zu stellen, die sich auf jede Aussage stürzen, die nicht 100% korrekt ist und jeden Sonderfall berücksichtigt.
-
ingobulla schrieb:
Ich verstehe insbesondere nicht, warum der Compiler meint,
Node::Base_Nd::Site_Cntr
sei kein Typ.Site_Cntr ist ein abhängiger Bezeichner und Base_Nd<N, C, IC, T> verweist nicht auf die "current instantiation", also muss der Compiler annehmen, dass Site_Cntr kein Typ ist, ein Lookup ist an dieser Stelle nicht möglich. typename sollte helfen:
template<class N, class C, class IC, class T> boost::shared_ptr< typename Node::Base_Nd<N, C, IC, T>::Site_Cntr > Node::Base_Nd<N, C, IC, T>::site_cntr() const { return m_site_cntr; }
template<class N, class C, class IC, class T> auto Node::Base_Nd<N, C, IC, T>::site_cntr() const -> boost::shared_ptr< Site_Cntr > { return m_site_cntr; }
ist allerdings einfacher.
Der Einwand von SeppJ ist trotzdem zu beachten.
-
camper schrieb:
verweist nicht auf die "current instantiation"
Tatsächlich?
A name refers to the current instantiation if it is
— in the definition of a primary class template or a member of a primary class template, the name of the class template followed by the template argument list of the primary template (as described below) enclosed in<>
(or an equivalent template alias specialization),Edit: nvm, das stimmt so natürlich nicht.
-
Arcoth schrieb:
camper schrieb:
verweist nicht auf die "current instantiation"
Tatsächlich?
A name refers to the current instantiation if it is
— in the definition of a primary class template or a member of a primary class template, the name of the class template followed by the template argument list of the primary template (as described below) enclosed in<>
(or an equivalent template alias specialization),Genau. Allerdings solltest du das noch näher erläutern, der Laie könnte sonst annehmen, das hier ein Widerspruch vorliegt.
-
Genau. Allerdings solltest du das noch näher erläutern, der Laie könnte sonst annehmen, das hier ein Widerspruch vorliegt.
Das kann ich nicht. Ich ahne, dass die Definition eines Memberfunktionstemplates "for the purpose of determining whether a name refers to the current instantiation" wahrscheinlich erst nach der parameter-declaration-clause eintritt, aber ich kann das nicht belegen.
-
Ich habe was gefunden, aber es ist eine etwas andere Erklärung...
§14.6/7 schrieb:
Within the definition of a class template or within the definition of a member of a class template following the declarator-id, the keyword
typename
is not required when referring to the name of a previously declared member of the class template that declares a type.
[ Note: such names can be found using unqualified name lookup (3.4.1), class member lookup (3.4.3.1) into the current instantiation (14.6.2.1), or class member access
expression lookup (3.4.5) when the type of the object expression is the current instantiation (14.6.2.2). — end note ]Allerdings erklärt das nichts a priori.
-
SeppJ schrieb:
Das Vorhaben ist von vornherein verdammt, da du Definitionen von Templates an der Stelle vorliegen müssen, wo sie instanziert werden ~(oder genauer: Sie müssen mindestens einmal vorgelegen haben, wenn eine spezielle Instanz erzeugt werden soll)~. Üblicherweise geht das nur, wenn die Definition in einem Header steht ~(außer du instanzierst alles was du brauchst explizit in der Sourcedatei, womit aber irgendwie der Sinn von Templates futsch wäre)~.
Die kleingeschriebenen Passagen kannst du ignorieren, die sind nur da, um die Klugscheißer ruhig zu stellen, die sich auf jede Aussage stürzen, die nicht 100% korrekt ist und jeden Sonderfall berücksichtigt.
Sorry, das hatte ich ganz verdrängt: Ich instanziere alles explizit. Das hatte ich so gemacht, da es letztlich um eine sehr überschaubare Anzahl an sehr speziellen Graphen (und deren Knoten) geht, die nur Evolutionsbiologen interessiert.
-
@camper: Kriegen wir noch die richtige Erklärung?