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 aber

    boost::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.


  • Mod

    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.


  • Mod

    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.


  • Mod

    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.


  • Mod

    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.


  • Mod

    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.


  • Mod

    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.


  • Mod

    @camper: Kriegen wir noch die richtige Erklärung?


Anmelden zum Antworten