Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Returning nested class within template class from member function.

Reply
Thread Tools

Returning nested class within template class from member function.

 
 
jason.cipriani@gmail.com
Guest
Posts: n/a
 
      12-02-2008
I have some code like this that won't compile:

template <typename T> class MyClass {
public:
class Nested { };
Nested f ();
};

template <typename T> MyClass<T>::Nested f () { // <---problem
return Nested();
}

"Nested" is a non-template class, nested inside the template class
"MyClass". The MyClass member function f() returns a "Nested", and is
defined outside of the class declaration. I receive the following
error from Comeau (and similar errors from other compilers):

"ComeauTest.c", line 7: error: nontype "MyClass<T>::Nested [with T=T]"
is not a
type name
template <typename T> MyClass<T>::Nested f () {

What is the correct syntax to use here? I can't figure out how to make
this work (or if it's just not possible). Putting the definition of f
() right in the class declaration does work fine, but I'd like to keep
it outside, but mostly I'm curious about the syntax.

Thanks,
JC
 
Reply With Quote
 
 
 
 
jason.cipriani@gmail.com
Guest
Posts: n/a
 
      12-02-2008
On Dec 1, 10:52*pm, "(E-Mail Removed)"
<(E-Mail Removed)> wrote:
> I have some code like this that won't compile:
>
> template <typename T> class MyClass {
> public:
> * * * * class Nested { };
> * * * * Nested f ();
>
> };
>
> template <typename T> MyClass<T>::Nested f () { // <---problem
> * * * * return Nested();
>
> }
>
> "Nested" is a non-template class, nested inside the template class
> "MyClass". The MyClass member function f() returns a "Nested", and is
> defined outside of the class declaration. I receive the following
> error from Comeau (and similar errors from other compilers):
>
> "ComeauTest.c", line 7: error: nontype "MyClass<T>::Nested [with T=T]"
> is not a
> * * * * * type name
> * template <typename T> MyClass<T>::Nested f () {
>
> What is the correct syntax to use here? I can't figure out how to make
> this work (or if it's just not possible). Putting the definition of f
> () right in the class declaration does work fine, but I'd like to keep
> it outside, but mostly I'm curious about the syntax.


Oops, I totally screwed that up! Forgot the "MyClass<T>::" before "f
()"... I got it figured out. This is correct:

template <typename T> MyClass<T>::Nested MyClass<T>::f () {
return Nested();
}

All right, but now that I've fixed *my* stupid mistake, Comeau
compiles it fine, except MS's VC++ 2008 compiler choked on it:

1>warning C4346: 'MyClass<T>::Nested' : dependent name is not a type
1> prefix with 'typename' to indicate a type
1>error C2143: syntax error : missing ';' before 'MyClass<T>::f'

But adding a "typename" in the middle there made it happy for some
reason:

template <typename T> typename MyClass<T>::Nested MyClass<T>::f () {
return Nested();
}

Jason






> Thanks,
> JC


 
Reply With Quote
 
 
 
 
olekk
Guest
Posts: n/a
 
      12-02-2008


http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> On Dec 1, 10:52�pm, "(E-Mail Removed)"
> <(E-Mail Removed)> wrote:
> > I have some code like this that won't compile:
> >
> > template <typename T> class MyClass {
> > public:
> > � � � � class Nested { };
> > � � � � Nested f ();
> >
> > };
> >
> > template <typename T> MyClass<T>::Nested f () { // <---problem
> > � � � � return Nested();
> >
> > }
> >
> > "Nested" is a non-template class, nested inside the template class
> > "MyClass". The MyClass member function f() returns a "Nested", and is
> > defined outside of the class declaration. I receive the following
> > error from Comeau (and similar errors from other compilers):
> >
> > "ComeauTest.c", line 7: error: nontype "MyClass<T>::Nested [with T=T]"
> > is not a
> > � � � � � type name
> > � template <typename T> MyClass<T>::Nested f () {
> >
> > What is the correct syntax to use here? I can't figure out how to make
> > this work (or if it's just not possible). Putting the definition of f
> > () right in the class declaration does work fine, but I'd like to keep
> > it outside, but mostly I'm curious about the syntax.

>
> Oops, I totally screwed that up! Forgot the "MyClass<T>::" before "f
> ()"... I got it figured out. This is correct:
>
> template <typename T> MyClass<T>::Nested MyClass<T>::f () {
> return Nested();
> }
>
> All right, but now that I've fixed *my* stupid mistake, Comeau
> compiles it fine, except MS's VC++ 2008 compiler choked on it:
>
> 1>warning C4346: 'MyClass<T>::Nested' : dependent name is not a type
> 1> prefix with 'typename' to indicate a type
> 1>error C2143: syntax error : missing ';' before 'MyClass<T>::f'
>
> But adding a "typename" in the middle there made it happy for some
> reason:
>
> template <typename T> typename MyClass<T>::Nested MyClass<T>::f () {
> return Nested();
> }


As compiler informs you - MyClass<T>::Nested is dependent name and
should be prefixed with typename keyword

template <typename T> typename MyClass<T>::Nested MyClass<T>::f () {
return Nested();
}

Regards
 
Reply With Quote
 
Triple-DES
Guest
Posts: n/a
 
      12-02-2008
On 2 Des, 09:18, Hendrik Schober <(E-Mail Removed)> wrote:
> (E-Mail Removed) wrote:
> > [...]
> > All right, but now that I've fixed *my* stupid mistake, Comeau
> > compiles it fine, except MS's VC++ 2008 compiler choked on it:

>
> > 1>warning C4346: 'MyClass<T>::Nested' : dependent name is not a type
> > 1> * * * *prefix with 'typename' to indicate a type
> > 1>error C2143: syntax error : missing ';' before 'MyClass<T>::f'

>
> > But adding a "typename" in the middle there made it happy for some
> > reason:

>
> > template <typename T> typename MyClass<T>::Nested MyClass<T>::f () {
> > * *return Nested();
> > }

>
> * I'd say the 'typename' is necessary ('Nested' is a nested identifier
> * depending on a template parameter, after all), but this seems to
> * counter all my experience regarding whether Comeau or VC is right,
> * whenever they disagree.
> * Am I wrong here, or would this really be a bug in Comeau??


Yes, typename is required here (14.6/3), so it would be non-conformant
to compile this without a diagnostic.
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      12-02-2008
On Dec 2, 9:18 am, Hendrik Schober <(E-Mail Removed)> wrote:
> (E-Mail Removed) wrote:
> > [...]
> > All right, but now that I've fixed *my* stupid mistake,
> > Comeau compiles it fine, except MS's VC++ 2008 compiler
> > choked on it:


> > 1>warning C4346: 'MyClass<T>::Nested' : dependent name is not a type
> > 1> prefix with 'typename' to indicate a type
> > 1>error C2143: syntax error : missing ';' before 'MyClass<T>::f'


> > But adding a "typename" in the middle there made it happy
> > for some reason:


> > template <typename T> typename MyClass<T>::Nested MyClass<T>::f () {
> > return Nested();
> > }


> I'd say the 'typename' is necessary ('Nested' is a nested
> identifier depending on a template parameter, after all),
> but this seems to counter all my experience regarding
> whether Comeau or VC is right, whenever they disagree.


> Am I wrong here, or would this really be a bug in Comeau??


Check the options it was invoked with. Comeau is a very
professional product, which means that it doesn't go around
breaking existing code if it can help it. So it almost
certainly has modes which accept this code, and others which
don't.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
jason.cipriani@gmail.com
Guest
Posts: n/a
 
      12-03-2008
On Dec 2, 9:33*am, Hendrik Schober <(E-Mail Removed)> wrote:
> James Kanze wrote:
> > On Dec 2, 9:18 am, Hendrik Schober <(E-Mail Removed)> wrote:
> >>(E-Mail Removed) wrote:
> >>> [...]
> >>> All right, but now that I've fixed *my* stupid mistake,
> >>> Comeau compiles it fine, except MS's VC++ 2008 compiler
> >>> choked on it:

>
> >>> 1>warning C4346: 'MyClass<T>::Nested' : dependent name is not a type
> >>> 1> * * * *prefix with 'typename' to indicate a type
> >>> 1>error C2143: syntax error : missing ';' before 'MyClass<T>::f'

>
> >>> But adding a "typename" in the middle there made it happy
> >>> for some reason:

>
> >>> template <typename T> typename MyClass<T>::Nested MyClass<T>::f () {
> >>> * *return Nested();
> >>> }

>
> >> * I'd say the 'typename' is necessary ('Nested' is a nested
> >> * identifier depending on a template parameter, after all),
> >> * but this seems to counter all my experience regarding
> >> * whether Comeau or VC is right, whenever they disagree.

>
> >> * Am I wrong here, or would this really be a bug in Comeau??

>
> > Check the options it was invoked with. *Comeau is a very
> > professional product, which means that it doesn't go around
> > breaking existing code if it can help it. *So it almost
> > certainly has modes which accept this code, and others which
> > don't.

>
> * Good thought, however, it does accept this
>
> * * template <typename T> class MyClass {
> * * public:
> * * * class Nested { };
> * * * Nested f ();
> * * };
>
> * * template <typename T> MyClass<T>::Nested MyClass<T>::f()
> * * {
> * * * return Nested();
> * * }
>
> * as
>
> * * Comeau C/C++ 4.3.10.1 (Oct *6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
> * * Copyright 1988-2008 Comeau Computing. *All rights reserved.
> * * MODE:strict errors C++ noC++0x_extensions
>
> * so it seems indeed this is a bug in Comeau.


Weird, I just immediately assumed that VS was the broken one. I did
not try with any other compiler besides VS and Comeau. I will report
the bug to Comeau and see what they say.

Jason
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      12-03-2008
On Dec 2, 3:33 pm, Hendrik Schober <(E-Mail Removed)> wrote:
> James Kanze wrote:
> > On Dec 2, 9:18 am, Hendrik Schober <(E-Mail Removed)> wrote:
> >> (E-Mail Removed) wrote:
> >>> [...]
> >>> All right, but now that I've fixed *my* stupid mistake,
> >>> Comeau compiles it fine, except MS's VC++ 2008 compiler
> >>> choked on it:


> >>> 1>warning C4346: 'MyClass<T>::Nested' : dependent name is not a type
> >>> 1> prefix with 'typename' to indicate a type
> >>> 1>error C2143: syntax error : missing ';' before 'MyClass<T>::f'


> >>> But adding a "typename" in the middle there made it happy
> >>> for some reason:


> >>> template <typename T> typename MyClass<T>::Nested MyClass<T>::f () {
> >>> return Nested();
> >>> }


> >> I'd say the 'typename' is necessary ('Nested' is a nested
> >> identifier depending on a template parameter, after all),
> >> but this seems to counter all my experience regarding
> >> whether Comeau or VC is right, whenever they disagree.


> >> Am I wrong here, or would this really be a bug in Comeau??


> > Check the options it was invoked with. Comeau is a very
> > professional product, which means that it doesn't go around
> > breaking existing code if it can help it. So it almost
> > certainly has modes which accept this code, and others which
> > don't.


> Good thought, however, it does accept this


> template <typename T> class MyClass {
> public:
> class Nested { };
> Nested f ();
> };


> template <typename T> MyClass<T>::Nested MyClass<T>::f()
> {
> return Nested();
> }


> as


> Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
> Copyright 1988-2008 Comeau Computing. All rights reserved.
> MODE:strict errors C++ noC++0x_extensions


> so it seems indeed this is a bug in Comeau.


I don't think so. The typename here is optional, since Nested
is not a dependent name, but a locally declared name. If you
used MyClass<T>::Nested in the definition of another template,
the typename would be necessary, but not here. But IMHO, the
standard is far from clear about this. It goes into detail with
regards to when an expression is dependant, but it really
doesn't say much about names in declarations. About the only
really relevant text I can find is right at the start of 14.6,
where it says that "Three kinds of names can be used[...]", and
places names declared within the template itself in the same
category as the name of the template, i.e. locally declared. So
while Nested in MyClass<T>::Nested obviously depends on T, it
doesn't depend on T in the sense of the standard. (This makes
sense, of course, in that the compiler can easily determine that
Nested is a type; in the definition of template members, it
doesn't have to worry about specializations.)

FWIW: both g++ and Sun CC require the typename as well.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
Triple-DES
Guest
Posts: n/a
 
      12-03-2008
On 3 Des, 10:15, James Kanze <(E-Mail Removed)> wrote:
> On Dec 2, 3:33 pm, Hendrik Schober <(E-Mail Removed)> wrote:
> > Good thought, however, it does accept this
> > template <typename T> class MyClass {
> > public:
> > class Nested { };
> > Nested f ();
> > };
> > template <typename T> MyClass<T>::Nested MyClass<T>::f()
> > {
> > return Nested();
> > }
> > as
> > Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
> > Copyright 1988-2008 Comeau Computing. All rights reserved.
> > MODE:strict errors C++ noC++0x_extensions
> > so it seems indeed this is a bug in Comeau.

>
> I don't think so. The typename here is optional, since Nested
> is not a dependent name, but a locally declared name. If you
> used MyClass<T>::Nested in the definition of another template,
> the typename would be necessary, but not here. But IMHO, the
> standard is far from clear about this. It goes into detail with
> regards to when an expression is dependant, but it really
> doesn't say much about names in declarations. About the only
> really relevant text I can find is right at the start of 14.6,
> where it says that "Three kinds of names can be used[...]", and
> places names declared within the template itself in the same
> category as the name of the template, i.e. locally declared. So
> while Nested in MyClass<T>::Nested obviously depends on T, it
> doesn't depend on T in the sense of the standard. (This makes
> sense, of course, in that the compiler can easily determine that
> Nested is a type; in the definition of template members, it
> doesn't have to worry about specializations.)


Nevertheless, even locally declared names are considered dependent if
the name is qualified, per the current standard [14.6.2.1/1],
[14.6/6].

Consider:

template <typename T>
struct MyClass
{
class Nested { };
Nested f () const; // ok
MyClass<T>::Nested f(); // ill-formed, 'typename' required
};

Note that Comeau online seems to accept this in 'strict' mode, which
is not conforming to C++03.

But according to issue 224:
The decision on whether a name is dependent or non-dependent should be
based on lookup, not on the form of the name: if the name can be
looked up in the definition context and cannot be anything else as the
result of specialization, the name should be non-dependent.
 
Reply With Quote
 
Vidar Hasfjord
Guest
Posts: n/a
 
      12-03-2008
On Dec 3, 9:15*am, James Kanze <(E-Mail Removed)> wrote:
> On Dec 2, 3:33 pm, Hendrik Schober <(E-Mail Removed)> wrote:
> > [...]
> > * * template <typename T> class MyClass {
> > * * public:
> > * * * class Nested { };
> > * * * Nested f ();
> > * * };
> > * * template <typename T> MyClass<T>::Nested MyClass<T>::f()
> > * * {
> > * * * return Nested();
> > * * }
> > *[...]

>
> I don't think so. *The typename here is optional, since Nested
> is not a dependent name, but a locally declared name. *If you
> used MyClass<T>::Nested in the definition of another template,
> the typename would be necessary, but not here.


IOW, the member function template definition for f will only be
matched and instatiated for the MyClass base template, not any
(partial) specializations of MyClass, so the declaration of Nested is
fixed and typename should be implicit.

>*But IMHO, the standard is far from clear about this.


Maybe the standard should give compilers some leeway on this. As far
as usage is concerned, requiring 'typename' here has little
consequence.

BTW, if I'm not mistaken the return part of the new C++0x style
function syntax is in the same scope as the function, and the above
can then be simplified to

template <typename T>
auto MyClass <T>::f () -> Nested {return Nested ();}

Regards,
Vidar Hasfjord
 
Reply With Quote
 
jason.cipriani@gmail.com
Guest
Posts: n/a
 
      12-03-2008
On Dec 2, 7:26*pm, "(E-Mail Removed)"
<(E-Mail Removed)> wrote:
> On Dec 2, 9:33*am, Hendrik Schober <(E-Mail Removed)> wrote:
>
>
>
> > James Kanze wrote:
> > > On Dec 2, 9:18 am, Hendrik Schober <(E-Mail Removed)> wrote:
> > >>(E-Mail Removed) wrote:
> > >>> [...]
> > >>> All right, but now that I've fixed *my* stupid mistake,
> > >>> Comeau compiles it fine, except MS's VC++ 2008 compiler
> > >>> choked on it:

>
> > >>> 1>warning C4346: 'MyClass<T>::Nested' : dependent name is not a type
> > >>> 1> * * * *prefix with 'typename' to indicate a type
> > >>> 1>error C2143: syntax error : missing ';' before 'MyClass<T>::f'

>
> > >>> But adding a "typename" in the middle there made it happy
> > >>> for some reason:

>
> > >>> template <typename T> typename MyClass<T>::Nested MyClass<T>::f () {
> > >>> * *return Nested();
> > >>> }

>
> > >> * I'd say the 'typename' is necessary ('Nested' is a nested
> > >> * identifier depending on a template parameter, after all),
> > >> * but this seems to counter all my experience regarding
> > >> * whether Comeau or VC is right, whenever they disagree.

>
> > >> * Am I wrong here, or would this really be a bug in Comeau??

>
> > > Check the options it was invoked with. *Comeau is a very
> > > professional product, which means that it doesn't go around
> > > breaking existing code if it can help it. *So it almost
> > > certainly has modes which accept this code, and others which
> > > don't.

>
> > * Good thought, however, it does accept this

>
> > * * template <typename T> class MyClass {
> > * * public:
> > * * * class Nested { };
> > * * * Nested f ();
> > * * };

>
> > * * template <typename T> MyClass<T>::Nested MyClass<T>::f()
> > * * {
> > * * * return Nested();
> > * * }

>
> > * as

>
> > * * Comeau C/C++ 4.3.10.1 (Oct *6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
> > * * Copyright 1988-2008 Comeau Computing. *All rights reserved.
> > * * MODE:strict errors C++ noC++0x_extensions

>
> > * so it seems indeed this is a bug in Comeau.

>
> Weird, I just immediately assumed that VS was the broken one. I did
> not try with any other compiler besides VS and Comeau. I will report
> the bug to Comeau and see what they say.


FWIW, GCC (3.4.5 mingw) also does not accept it without the
"typename", although the error message is less than informative:

$ g++ testme.cpp
testme.cpp:7: error: expected constructor, destructor, or type
conversion before
"MyClass"


Jason
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
returning pointer to template objects in nested template classes Javier Montoya C++ 4 11-20-2010 11:19 PM
problem with a function template returning a private nested class ofa class template ymost@hotmail.com C++ 2 12-28-2008 10:43 AM
dealing with nested xml within nested xml within...... Ultrus Python 3 07-09-2007 09:00 PM
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM
parse error in gcc but success in vc.net, call a non_template class's template member function from a template class's member function! ken C++ 2 06-28-2005 06:57 AM



Advertisments