Datenmember als Nicht-Typ-Templateparameter innerhalb der eigenen Klasse



  • Folgendes funktioniert problemlos:

    struct A;
    
    template<int (A::*)>
    struct test {};
    
    struct A
    {
        int foo;
    };
    
    int main()
    {
        test<&A::foo> x;
    }
    

    Wenn ich aber die Dekleration von x in A reinnehmen will, geht es nicht mehr (MSVC 2010). Also

    struct A;
    
    template<int (A::*)>
    struct test {};
    
    struct A
    {
        int foo;
        test<&A::foo> x; // <-- Fehler
    };
    
    int main() {}
    

    Die Fehlermeldung ist wenig hilfreich:

    1>...\main.cpp(9): error C2327: 'A::foo': Ist kein Typname, nicht statisch und kein Enumerator
    1>...\main.cpp(9): error C2065: 'foo': nichtdeklarierter Bezeichner
    

    Das beispiel funktioniert, wenn foo eine Funktion ist (natürlich bei entsprechender Anpassung der Templateparameter von test ).

    Hat irgendwer eine Erklärung dafür? Ist das im Standard so vorgeschrieben? (ich möchte mal nicht gleich von einem Bug im Visual Studio ausgehen).
    Ich könnte mir das so erklären, dass &A::foo ja ein Offset darstellt und der Compiler das zum Zeitpunkt der Dekleration eventuell noch nicht wissen kann, da eventuell danach eine virtuelle Funktion kommen könnte und sich somit das Offset um den vptr verschieben würde. Aber gut, dann muss er eben dahinter gucken. Selbstverständlich bleibt der Fehler auch, wenn ich davor eine virtuelle Funktion definiere.
    Ansonsten hab ich aber keine wirkliche Erklärung für das Verhalten.



  • G++ 4.4.5 (ohne -std=c++0x) und http://www.comeaucomputing.com/tryitout/ (ebenfalls ohne 0x) nehmen auch die zweite Version anstandslos.

    Was der Bill da zu meckern hat, versteh ich nicht. 😉


Anmelden zum Antworten