Problem mit Template Spezialisierung
-
Hi,
ich hab folgenden Code:
template <class T> struct MyClass { template <int N1 = 0, int N2 = 1> struct Count { static const int result = 0; }; template <> struct Count<> { // error C2976: 'MyClass<T>::Count' : too few template arguments static const int result = 1; }; }; int main() { int i = MyClass<long>::Count<>::result; std::cout << i; return 0; }
An besagter Stelle gibt mir der MSC 7.1 entsprechenden Fehler aus. Wieso das? Es sollte doch möglich sein, alle Template Parameter aus den Defaults herzuleiten. Eigenartigerweise funktioniert alles wunderbar, wenn MyClass keine Template Klasse ist.
struct MyClass { ... }; ... int i = MyClass::Count<>::result;
Kann mir das jemand erklären?
-
struktur templates kannst du vergessen, sie werden vom standard nicht unterstützt
achja, der bcb 6.0 gibt mir eine ganze weitere Latte an fehlermeldungen, aber so krieg ichs zum laufen:
template <int N1=0,int N2=1> class Count { static const int result = 0; }; class Count<> { // error C2976: 'MyClass<T>::Count' : too few template arguments static const int result = 1; }; template<class T> class MyClass { Count<1,1> x; Count<> y; };
hoffe, das konnte dir helfen
-
otze schrieb:
struktur templates kannst du vergessen, sie werden vom standard nicht unterstützt
wo hast du den Blödsinn her? Eine Struktur ist nichts anderes als eine Klasse, mit dem Unterschied - die Members sind per default public, auch bei der Ableitung. Der Standard erlaubt sogar union-Templates.
-
Hi,
warum versuchts du eigentlich eine template klasse ohne argumente zu erstellen ? das kann doch gar nicht erst funktionieren:
template <> struct Count<> { // error C2976: 'MyClass<T>::Count' : too few template arguments static const int result = 1; }; };
lass das template weg:
struct Count { static const int result = 1; }; };
-
eViLiSSiMo schrieb:
Hi,
warum versuchts du eigentlich eine template klasse ohne argumente zu erstellen ? das kann doch gar nicht erst funktionieren:
doch kann es, das nennst sich Template-Spezialisierung. Auch wenn Template Default-Parameter bei der generellen Klasse vorhanden sind, müssen diese bei der Spezialisierung explizit angegeben werden, deshalb der Fehler.
-
das funktioniert, aufgrund der default parameter in der definition von count wird Count<> zu einer spezialisierung für den fall der defaultparameter.
@Shlo hmm,ich hab meine aussagen auf nen compilererror gestützt, der grad beim experimentieren aufgetreten ist, und der besagt hat, dass nur klassen und funktionen templates sein dürfen
.
-
Templatespezialisierung nicht auf Namespacescope? Wo gibt's denn sowas?
-
otze schrieb:
@Shlo hmm,ich hab meine aussagen auf nen compilererror gestützt, der grad beim experimentieren aufgetreten ist, und der besagt hat, dass nur klassen und funktionen templates sein dürfen
.
Strukturen *sind* aber Klassen. Jedenfalls wirst du im Standard oder Stroustrup kein Extra-Kapitel über Strukturen finden, das läuft alles unter Klassen.
-
Helium schrieb:
Templatespezialisierung nicht auf Namespacescope? Wo gibt's denn sowas?
Beim VC. Zumindest bis Version 7.0. Ist aber natürlich eine Spracherweiterung und *kein* legales Standard-C++.
-
otze schrieb:
aufgrund der default parameter in der definition von count wird Count<> zu einer spezialisierung für den fall der defaultparameter.
Yep, genau dafür war es eigentlich gedacht.
HumeSikkins schrieb:
Helium schrieb:
Templatespezialisierung nicht auf Namespacescope? Wo gibt's denn sowas?
Beim VC. Zumindest bis Version 7.0. Ist aber natürlich eine Spracherweiterung und *kein* legales Standard-C++.
Offensichtlich auch Version 7.1. Denn wie gesagt, ist MyClass keine Template Klasse, funktionierts ja.
Wie auch immer. Kann ich davon ausgehen, dass Template Klassen innerhalb von anderen Template Klassen deklariert werden dürfen? Der Standard erwähnt hier Member Templates (14.5.2). So, wenn die Spezialisierung nur im Namespacescope möglich ist, hab ich folgendes probiert:
template <class T> struct MyClass { template <int N1 = 0, int N2 = 1> struct Count { static const int result = 0; }; }; template <class T> template <> struct MyClass<T>::Count<> { static const int result = 1; };
Leider funktioniert das auch nicht.
OK, neue Idee. Hab jetzt folgendes probiert:
struct MyClassCountContainer { template <int N1 = 0, int N2 = 1> struct Count { static const int result = 0; }; }; template <> struct MyClassCountContainer::Count<> { static const int result = 1; }; template <class T> struct MyClass : public MyClassCountContainer { };
Siehe da, jetzt klappt's. Ist diese Lösung nun standardkonform? Oder gibts nen besseren Workaround?
-
kann mir nich helfen, aber das sieht irgendwie ekelhaft aus^^
//edit
der bcb 6.0 weigert sich, das zu compilieren,liegt das daran, dass es nur ne definition, und keine deklaration ist?
-
otze schrieb:
kann mir nich helfen, aber das sieht irgendwie ekelhaft aus
Seh ich genauso.
Was sagt denn der bcb genau?
-
war da nicht mal was damit, dass man Member nicht spezialisieren kann?
Der GCC 3.3.3 weigert sich auch
-
der bcb sagt jede menge^^
struct MyClassCountContainer { template <int N1 = 0, int N2 = 1>//[C++ Error] Unit1.cpp(4): E2270 > expected struct Count { static const int result = 0; };//[C++ Error] Unit1.cpp(8): E2321 Declaration does not specify a tag or an identifier }; template <> struct MyClassCountContainer::Count<>//[C++ Error] Unit1.cpp(12): E2451 Undefined symbol 'Count' { static const int result = 1; };//[C++ Error] Unit1.cpp(15): E2428 Templates must be classes or functions template <class T> struct MyClass : public MyClassCountContainer { };
-
@otze:
soweit ich das sehe, ist der code aber korrekt.
-
tja, wenns aufm bcb und dem GCC nicht klappt, kann da aber was net stimmen^^
-
Mein gcc (3.3.2) schluckt den code aber:
struct MyClassCountContainer { template <int N1 = 0, int N2 = 1> expected struct Count { static const int result = 0; }; }; template <> struct MyClassCountContainer::Count<> //alternativ: //struct MyClassCountContainer::Count<0,1> { static const int result = 1; }; template <class T> struct MyClass : public MyClassCountContainer { };
oder meinst du einen anderen code?
-
ne das is der der gemeint war.
irgendwelche spracherweiterungen an?
-
otze schrieb:
ne das is der der gemeint war.
irgendwelche spracherweiterungen an?ich kompiliere per
g++ -W -Wall -std=c++98 -Woverloaded-virtual -pedantic -Wfloat-equal -Wundef -Wpointer-arith -Wconversion -Wsign-compare -Wuninitialized -O -Wunused -Wunreachable-code -DDEBUG $*
Aber einfach per
g++ test.cpp
klappt der code auch...und Comeau findet den code auch ok.
-
Morgen,
Mein BCB5 schluckt den Code ohne Probleme.