Undefined Reference bei statischer Methode / Template



  • Es ging um die Initialisierung. Mehr nicht. Aber mir egal, lösch halt meine Posts, wenns dir Spaß macht.



  • OK, die Frage war vielleicht nicht ganz klar. Also nochmal.

    Der aktuelle Standard verlangt dass man integrale static const nochmal ausserhalb der Klasse definiert, auch wenn sie bereits "inline" definiert wurden. Und zwar in genau einer TU - genau so wie nicht "inline" definierte static const.

    Das nervt.

    Und daher macht es keiner (ich sehe es zumindest so-gut-wie nie).

    Die beiden grossen Compiler (GCC und MSVC) fressen das auch ohne weiteres, obwohl es laut Standard ein Fehler ist.

    Was funktioniert und was nicht ist mir daher auch einigermassen klar.

    Die Frage ist: erlaubt der neue Standard das jetzt offiziell, oder nicht?



  • If a static data member is of const literal type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. —end note] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.

    Paragraph 9.4.2 Absatz 3

    Wenn ich das richtig gelesen habe, ist es immer noch erforderlich.



  • 314159265358979 schrieb:

    If a static data member is of const literal type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. —end note] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.

    Paragraph 9.4.2 Absatz 3

    Wenn ich das richtig gelesen habe, ist es immer noch erforderlich.

    Ich fürchte, ich lese, daß man das member nicht in der UE definieren muß, solange man es nur als Konstante benutzt, wie in Arraygrößenangaben oder arithmetischen Ausdrücken. Also dürfen wir weitermachen wie bisher.
    Nur, wenn man es ODR-benutzt, muß man es auch noch definieren. Was ist ODR-benutzen?



  • Es tut mir leid die aktuelle Diskussion zu unterbrechen,
    aber ich bin mit der Korrektur meines Quellcodes trotz allem Genannten ein wenig überfordert.
    Kann mir jemand den korrigierten Quellcode aufschreiben?
    Vielen Dank,
    Adam S



  • Meine Lösung auf der ersten Seite, ergänzt um ein typename vor dem Rückgabetyp, vergleiche die Antwort auf meine Frage von Nexus.



  • Vielen Dank!
    Solch ein Konstrukt habe ich noch nie verwendet, ich entschuldige mich für meine Begriffsstutzigkeit.

    Es funktioniert mit folgenden Zeilen hinter der Klassendefinition.

    template <class ResourceType>
    typename ResourceManager<ResourceType>::ResourceMap ResourceManager<ResourceType>::resourcemap = ResourceManager<ResourceType>::ResourceMap();
    


  • No clockthing!

    Aber es könnte genausogut lauten:

    template <class ResourceType>
    typename ResourceManager<ResourceType>::ResourceMap ResourceManager<ResourceType>::resourcemap;
    

    Und durch die Methode des genauen hinsehens sieht man, dass es dem Muster einer normalen Variablendefinition gleichkommt, nur dass die Typen und Klassen von einem weiteren Typ abhängen.


Anmelden zum Antworten