From: persres on
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
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
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
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! ]