Seltsamer Fehler beim template meta programming.



  • Hallo Forum!

    Ich habe den folgenden Quellcode:

    template<int x, int y>
    class add
    {
    public:
      const static int is = x + y;
    };
    
    template <int x>
    class add1
    {
    public:
      const int is = add<1, x>::is;
    };
    

    Wenn ich den mit g++ -std=c++11 compiliere bekomme ich die folgenden Fehler, die ich nicht verstehe:

    test.cpp:12:25: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       const int is = add<1, x>::is;
                             ^
    test.cpp:12:25: error: expected ‘;’ at end of member declaration
    test.cpp:12:25: error: declaration of ‘const int add1<x>::x’
    test.cpp:8:11: error:  shadows template parm ‘int x’
     template <int x>
               ^
    test.cpp:12:26: error: expected unqualified-id before ‘>’ token
       const int is = add<1, x>::is;
                              ^
    test.cpp:12:22: error: wrong number of template arguments (1, should be 2)
       const int is = add<1, x>::is;
                          ^
    test.cpp:2:7: error: provided for ‘template<int x, int y> class add’
     class add
           ^
    

    Wenn ich in Zeile 12 die RHS in Klammern setze, treten die Fehler nicht auf:

    const int is = (add<1, x>::is);
    

    Wenn ich in Zeile 12 das x und die 1 austausche, treten die Fehler ebenfalls nicht auf:

    const int is = add<x, 1>::is;
    

    Wenn ich in Zeile 12 ein static hinzufüge, treten die Fehler ebenfalls nicht auf:

    const static int is = add<1, x>::is;
    

    Wenn ich den Code mit clang kompilieren treten die Fehler ebenfalls nicht auf.

    Was ist da los? Ist das vielleicht ein Bug in G++?

    Vielen Dank im Voraus!

    Mit freundlichen Grüßen
    Ǹíłŝ



  • Bei Add1 fehlt das static vor is. Das willst du auch aus semantischen Gründen.
    Die anderen "Lösungen" sehen nach Compilerbugs aus, ja.



  • Nathan schrieb:

    Bei Add1 fehlt das static vor is. Das willst du auch aus semantischen Gründen.

    Okay, warum brauche ich das static? Ich dachte in C++11 ist das dort nicht mehr nötig?



  • Hm?

    Das static macht natuerlich auch in c++11 einen Unterschied:

    class foo
    {
        int i;
        static int si; // ist nicht dasselbe wie i
    };
    

  • Mod

    Ich habe den folgenden Quellcode:

    Joa, der ist korrekt (i.e. standardkonform). Version von GCC?

    Ich dachte in C++11 ist das dort nicht mehr nötig?

    Korrekt. Nathan hat da wohl was verwechselt. (Oder ich misinterpretiere seinen Post.)



  • Ǹíł& schrieb:

    Wenn ich den mit g++ -std=c++11 compiliere bekomme ich die folgenden Fehler, die ich nicht verstehe:

    test.cpp:12:25: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
    

    Bist du sicher, dass du -std=c++11 übergeben hast?



  • Arcoth schrieb:

    Ich dachte in C++11 ist das dort nicht mehr nötig?

    Korrekt. Nathan hat da wohl was verwechselt. (Oder ich misinterpretiere seinen Post.)

    Ich ging davon aus, dass er wegen TMP eine static Membervariable wollte. 💡


  • Mod

    Nathan schrieb:

    Arcoth schrieb:

    Ich dachte in C++11 ist das dort nicht mehr nötig?

    Korrekt. Nathan hat da wohl was verwechselt. (Oder ich misinterpretiere seinen Post.)

    Ich ging davon aus, dass er wegen TMP eine static Membervariable wollte. 💡

    Ja, das hast du bereits dadurch deutlich gemacht dass du

    Das willst du auch aus semantischen Gründen.

    geschrieben hast. Beachte aber den Fett markierten Teil: Was war der primäre, andere Grund? Oder verstehe ich "semantischer Grund" falsch? Das bezieht sich doch darauf dass man bei TMP fast ausschließlich statische Member hat.



  • Arcoth schrieb:

    Das willst du auch aus semantischen Gründen.

    geschrieben hast. Beachte aber den Fett markierten Teil: Was war der primäre, andere Grund? Oder verstehe ich "semantischer Grund" falsch? Das bezieht sich doch darauf dass man bei TMP fast ausschließlich statische Member hat.

    Das "semantische Gründe" bezog sich auf die Tatsache, dass man mit statischen Member arbeitet, ja.
    Der andere Grund wäre: damit es kompiliert.
    Ich habe den Post vom TO nicht genau gelesen und ging von der Fehlermeldung davon aus, dass er kein C++11 verwendet. Demzufolge ist der primäre Grund, dass Ding zum Compilieren zu bringen und deshalb habe ich auch den Rest als Bug interpretiert.



  • backquestion schrieb:

    Ǹíłŝ schrieb:

    Wenn ich den mit g++ -std=c++11 compiliere bekomme ich die folgenden Fehler, die ich nicht verstehe:

    test.cpp:12:25: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
    

    Bist du sicher, dass du -std=c++11 übergeben hast?

    Du hast recht, das hatte ich vergessen. Mit dem Parameter bleiben der Rest der Fehlermeldungen allerdings die selben.

    Arcoth schrieb:

    Ich habe den folgenden Quellcode:

    Joa, der ist korrekt (i.e. standardkonform). Version von GCC?

    Ich habe die aktuelle GCC Version aus dem testing Zweir von Arch Linux:
    gcc version 4.9.2 20150304 (prerelease) (GCC)

    Hm, vielleicht sollte ich kein Prerelease verwenden. 😃
    Mal schauen, ob es einen Eintrag in Bugzilla gibt...


  • Mod

    Hm, vielleicht sollte ich kein Prerelease verwenden.

    Quatsch, der Bug ist im normalen Release ebenfalls vorhanden. Siehe Coliru - also ja, hast nen Bug gefunden, Glückwunsch. Reporten und die Sache ist abgehakt. 🙂



  • Arcoth schrieb:

    also ja, hast nen Bug gefunden, Glückwunsch. Reporten und die Sache ist abgehakt. 🙂

    Der Bug ist offenbar schon seit drei Jahren bekannt und wird nicht gefixt:
    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52595
    Seltsam. 😕


Anmelden zum Antworten