 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
gogo1969@gmail.com Guest
|
Posted: Sun Feb 05, 2006 2:00 pm Post subject: Template Member Functions of Template Classes |
|
|
Hello,
I was wondering why the following code compiles with Intel C++ 8.0 and
MS VC++ 7.1 but not with gcc 4.0.1 and Comeau 4.3.3:
#include <iostream>
template < class T > struct B {
template < class O > static O CastTo( T t ) { return O( t ); }
};
template < class T > int convert( T t )
{
return B< T >::CastTo< int >( t );
// ^
// Comeau: Type not allowed
}
int main( int, char** )
{
std::cout << convert( 'c' );
return 0;
}
The problem is this line: 'B< T >::CastTo< int >( t );'
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Thomas Tutone Guest
|
Posted: Mon Feb 06, 2006 11:00 am Post subject: Re: Template Member Functions of Template Classes |
|
|
gogo1969 (AT) gmail (DOT) com wrote:
| Quote: | I was wondering why the following code compiles with Intel C++ 8.0 and
MS VC++ 7.1 but not with gcc 4.0.1 and Comeau 4.3.3:
#include <iostream
template < class T > struct B {
template < class O > static O CastTo( T t ) { return O( t ); }
};
template < class T > int convert( T t )
{
return B< T >::CastTo< int >( t );
}
int main( int, char** )
{
std::cout << convert( 'c' );
return 0;
}
The problem is this line: 'B< T >::CastTo< int >( t );'
|
Change it to:
return B< T >::template CastTo< int >( t );
Best regards,
Tom
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Valentin Samko Guest
|
Posted: Mon Feb 06, 2006 11:00 am Post subject: Re: Template Member Functions of Template Classes |
|
|
gogo1969 (AT) gmail (DOT) com wrote:
| Quote: | template < class T > struct B {
template < class O > static O CastTo( T t ) { return O( t ); }
};
template < class T > int convert( T t )
{
return B< T >::CastTo< int >( t );
}
The compiler does not know whether CastTo is a template or not. |
The correct code is
return B<T>::template CastTo<int>(t);
This may be obvious to you (that CastTo is a template member function) but not to the
compiler. Just consider the case when you later specialise your struct B for some type,
where CastTo is actually a member variable, and not a template, then you get an invalid
code which effectively means
return ( (B<T>::CastTo) < int ) > t;
By using the "template" keyword you explicitly state that CastTo is a template and the
following <int> is a template parameter, and not "less int greater".
--
Valentin Samko - http://www.valentinsamko.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Greg Herlihy Guest
|
Posted: Mon Feb 06, 2006 11:00 am Post subject: Re: Template Member Functions of Template Classes |
|
|
gogo1969 (AT) gmail (DOT) com wrote:
| Quote: | Hello,
I was wondering why the following code compiles with Intel C++ 8.0 and
MS VC++ 7.1 but not with gcc 4.0.1 and Comeau 4.3.3:
#include <iostream
template < class T > struct B {
template < class O > static O CastTo( T t ) { return O( t ); }
};
template < class T > int convert( T t )
{
return B< T >::CastTo< int >( t );
// ^
// Comeau: Type not allowed
}
|
The Intel and MS compilers apparently accept a more relaxed syntax in
this case (either because they have not been updated or, more likely,
probably to avoid this kind of question ).
Nevertheless, the proper syntax for calling one function template from
within another function template would be:
template <class T> int convert( T t )
{
return B<T>::template CastTo<int>( t );
}
Greg
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Mon Feb 06, 2006 11:01 am Post subject: Re: Template Member Functions of Template Classes |
|
|
"gogo1969 (AT) gmail (DOT) com" <gogo1969 (AT) gmail (DOT) com> writes:
| Quote: | #include <iostream
template < class T > struct B {
template < class O > static O CastTo( T t ) { return O( t ); }
|
Side note: I think that using the name O (or l or I for that matter)
is a very bad choice because these characters may be very hard to tell
from the digits 0 and 1.
| Quote: | };
template < class T > int convert( T t )
{
return B< T >::CastTo< int >( t );
// ^
// Comeau: Type not allowed
|
When the compiler parses this function template, it doesn't know what
the name CastTo names, because it is a dependant name. Even with the
base template's definition present just above; a specialization could
be defined later that could declare CastTo to name something different
than a member template.
According to the ISO C++ Standard, the compiler is required to assume
that CastTo does *not* name a member template in this case unless it
is told otherwise, as in:
return B<T>::template CastTo<int>(t);
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|