Prev: why are missing return statements from non-void functions not a
Next: why are missing return statements from non-void functions not a compilation error
From: persres on 29 Jul 2010 00:09 Hi, For a class ABC. Can we declare the Ctor as ABC::ABC()? In particular for a class template, what is the semantics? Please look at the code below. It doesn't compile on VC2008. class Base { public: Base::Base() {} virtual ~Base() {} } ; template <class T> class ABC : public Base { public: ABC::ABC() {} // Line 16 error ~ABC() {} }; int main() { ABC<int> sp; } The errors are - main.cpp(16) : error C3254: 'ABC<T>' : class contains explicit override '{ctor}' but does not derive from an interface that contains the function declaration main.cpp(18) : see reference to class template instantiation 'ABC<T>' being compiled main.cpp(16) : error C3244: 'ABC<T>::ABC(void)' : this method was introduced by '<Unknown>' not by 'Base' What do these errors mean? Is ABC::ABC legal for a plain class? Is it a specialization for a template class? Thanks -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Ulrich Eckhardt on 29 Jul 2010 04:01 persres wrote: > For a class ABC. Can we declare the Ctor as ABC::ABC()? > class Base > { > public: > Base::Base() {} > virtual ~Base() {} > } ; Everything in class Base is implicitly "in Base::", so there is no need to qualify this constructor with Base::. Also, IIRC, this code is simply ill-formed according to the C++ standard. I know that MSVC ignores that though. > template <class T> > class ABC : public Base > { > public: > ABC::ABC() {} // Line 16 error > ~ABC() {} > }; [...] > main.cpp(16) : error C3254: 'ABC<T>' : class contains explicit > override '{ctor}' but does not derive from an interface that contains > the function declaration > main.cpp(18) : see reference to class template instantiation 'ABC<T>' > being compiled > main.cpp(16) : error C3244: 'ABC<T>::ABC(void)' : this method was > introduced by '<Unknown>' not by 'Base' > > What do these errors mean? In short, it seems that the compiler complains that "ABC" is not a class. To some extent, the compiler is right, because ABC is not a class but a class template. As such, it rejects the "ABC::" qualification, I guess you could qualify it with "ABC<T>::". Note that it doesn't do so always, generally you can use ABC in a template class name and it implicitly becomes ABC<T>, like e.g. with the constructor and destructor. Remove the useless qualifications and you should be fine. Uli -- Sator Laser GmbH Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932 [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 29 Jul 2010 04:00 On 29 Jul., 17:09, persres <pers...(a)googlemail.com> wrote: > Hi, > For a class ABC. Can we declare the Ctor as ABC::ABC()? This syntax does not have a meaning, if the c'tor is defined within the class ABC. It is necessary to use this qualification, if the member were defined outside the class as in the following example: struct A { A(); // OK, just declared }; A::A() {} // Definition This makes sense, because the definition is in the context of the surrounding namespace. Within this context, a class member needs to be accessed via qualification with the class name (or via member access). > In particular for a class template, what is the semantics? > Please look at the code below. It doesn't compile on VC2008. The code is ill-formed and should be rejected. > class Base > { > public: > Base::Base() {} > virtual ~Base() {}} ; > > template <class T> > class ABC : public Base > { > public: > ABC::ABC() {} // Line 16 error > ~ABC() {} > }; > > int main() > { > ABC<int> sp; > } > > The errors are - > main.cpp(16) : error C3254: 'ABC<T>' : class contains explicit > override '{ctor}' but does not derive from an interface that contains > the function declaration > main.cpp(18) : see reference to class template instantiation 'ABC<T>' > being compiled > main.cpp(16) : error C3244: 'ABC<T>::ABC(void)' : this method was > introduced by '<Unknown>' not by 'Base' > > What do these errors mean? Is ABC::ABC legal for a plain class? Is it > a specialization for a template class? The compiler is just complaining that your code is ill- formed. The error message could be improved, but you cannot imply any reasonable interpretation from that. HTH & Greetings from Bremen, Daniel Kr�gler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Johannes Schaub (litb) on 29 Jul 2010 09:48
persres wrote: > Hi, > For a class ABC. Can we declare the Ctor as ABC::ABC()? > > In particular for a class template, what is the semantics? > Please look at the code below. It doesn't compile on VC2008. > class Base > { > public: > Base::Base() {} > virtual ~Base() {} > } ; > template <class T> > class ABC : public Base > { > public: > ABC::ABC() {} // Line 16 error > ~ABC() {} > }; > > int main() > { > ABC<int> sp; > } > > > > The errors are - > main.cpp(16) : error C3254: 'ABC<T>' : class contains explicit > override '{ctor}' but does not derive from an interface that contains > the function declaration > main.cpp(18) : see reference to class template instantiation 'ABC<T>' > being compiled > main.cpp(16) : error C3244: 'ABC<T>::ABC(void)' : this method was > introduced by '<Unknown>' not by 'Base' > > What do these errors mean? Is ABC::ABC legal for a plain class? Is it > a specialization for a template class? > Thanks > Normally, declarations of constructors don't use the usual declaration scheme. A declaration like "Base::Base() { }" does not say "declare Base in Base" but says "declare the constructor of Base". This is because constructors are declared by mentioning the name of its class as the declaration name. Now there are two reasons this is invalid code: * 8.3 says "A declarator-id shall not be qualified except for ...", not mentioning constructor declarations inside the class. * Name lookup at 3.4.3.1/1a says "If the nested-name-specifier nominates a class C, and the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C (clause 9), the name is instead considered to name the constructor of class C" Thus, your declaration is trying to refer to a constructor of ABC, instead of refering to your class. And, actually, the lookup will fail too because the point of declaration of the implicit declaration of the copy constructor can only be at the closing brace of the class definition (12.8/4) - too late for your lookup. This is why comeau/edg complains that qualified names are not allowed in the first below code. It tries to lookup "A::A" to a constructor, and knows it's not a type-name, so it interprets it as the declaration name, instead of the type of "*a", and errors out struct A { A::A *a; }; struct B { class B::B *b; }; // valid, inhibit ctor association -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |