Connecting Tech Pros Worldwide Help | Site Map

Types defined inside templates

Ruben Campos
Guest
 
Posts: n/a
#1: Jul 22 '05
I've found a problem with types defined inside a template. With a
non-template class, I can write the following:

// MyClass.hpp
class MyClass
{
// ...
typedef unsigned int MyType;
MyType MyMethod ( /* ... */ );
// ...
};

// MyClass.cpp
MyClass::MyType
MyClass::MyMethod ( /* ... */ )
{
// ...
}

This code works well. Of course, I can include a using declaration "using
MyClass::MyType" in MyClass.cpp file, before MyMethod implementation,
instead of specifying the path in its return value.

Well, my problem is that this don't work with templates:

// MyTemplate.hpp
template <typename T>
class MyTemplate
{
// ...
typedef unsigned int MyType;
MyType MyMethod ( /* ... */ );
// ...
};

// MyTemplate.cpp
template <typename T>
MyTemplate <T>::MyType
MyTemplate <T>::MyMethod ( /* ... */ )
{
// ...
}

Is there any alternative way to do this? I've thought to place type
definition outside the class, but this is not correct due to visibility
restrictions (it would make the type visible outside the class, which is not
always desired). Could I include a forward declaration inside the class
declaration (MyTemplate.hpp), and define it at the beginning of
MyTemplate.cpp?

Thank you very much in advance for your help :-)


Karthik Kumar
Guest
 
Posts: n/a
#2: Jul 22 '05

re: Types defined inside templates


Ruben Campos wrote:[color=blue]
> I've found a problem with types defined inside a template. With a
> non-template class, I can write the following:
>
> // MyClass.hpp
> class MyClass
> {
> // ...
> typedef unsigned int MyType;
> MyType MyMethod ( /* ... */ );
> // ...
> };
>
> // MyClass.cpp
> MyClass::MyType
> MyClass::MyMethod ( /* ... */ )
> {
> // ...
> }
>
> This code works well. Of course, I can include a using declaration "using
> MyClass::MyType" in MyClass.cpp file, before MyMethod implementation,
> instead of specifying the path in its return value.
>
> Well, my problem is that this don't work with templates:
>
> // MyTemplate.hpp
> template <typename T>
> class MyTemplate
> {
> // ...
> typedef unsigned int MyType;
> MyType MyMethod ( /* ... */ );
> // ...
> };
>
> // MyTemplate.cpp
> template <typename T>
> MyTemplate <T>::MyType
> MyTemplate <T>::MyMethod ( /* ... */ )
> {
> // ...
> }
>[/color]

Well - the *definition* for the template method ought to be
in a single header file and you cannot separate the declaration
and definition of templates, as you would do for classes. (
at least not until 'export' is widely implemented. Currently,
there are very few implementations that support that and so,
never bother anyway).

--
Karthik. http://akktech.blogspot.com .
' Remove _nospamplz from my email to mail me. '
Ruben Campos
Guest
 
Posts: n/a
#3: Jul 22 '05

re: Types defined inside templates


"Karthik Kumar" <kaykaylance_nospamplz@yahoo.com> escribió en el mensaje
news:418b458b$1@darkstar...[color=blue]
> Ruben Campos wrote:[color=green]
>> I've found a problem with types defined inside a template. With a
>> non-template class, I can write the following:
>>
>> // MyClass.hpp
>> class MyClass
>> {
>> // ...
>> typedef unsigned int MyType;
>> MyType MyMethod ( /* ... */ );
>> // ...
>> };
>>
>> // MyClass.cpp
>> MyClass::MyType
>> MyClass::MyMethod ( /* ... */ )
>> {
>> // ...
>> }
>>
>> This code works well. Of course, I can include a using declaration "using
>> MyClass::MyType" in MyClass.cpp file, before MyMethod implementation,
>> instead of specifying the path in its return value.
>>
>> Well, my problem is that this don't work with templates:
>>
>> // MyTemplate.hpp
>> template <typename T>
>> class MyTemplate
>> {
>> // ...
>> typedef unsigned int MyType;
>> MyType MyMethod ( /* ... */ );
>> // ...
>> };
>>
>> // MyTemplate.cpp
>> template <typename T>
>> MyTemplate <T>::MyType
>> MyTemplate <T>::MyMethod ( /* ... */ )
>> {
>> // ...
>> }
>>[/color]
>
> Well - the *definition* for the template method ought to be
> in a single header file and you cannot separate the declaration
> and definition of templates, as you would do for classes. (
> at least not until 'export' is widely implemented. Currently,
> there are very few implementations that support that and so,
> never bother anyway).
>
> --
> Karthik. http://akktech.blogspot.com .
> ' Remove _nospamplz from my email to mail me. '[/color]

You're right. I forgot to say that, in the template case, the .cpp file is
included inside the .hpp file. In fact, when considering optimization with
inline methods, I use a three file (.hpp, .cpp and .inl) scheme like this:

// MyTemplate.hpp
// MyTemplate <T> header file
template <typename T>
class MyTemplate
{
// MyTemplate <T> class declaration ...
};

#ifndef DISABLE_INLINE
#include "MyTemplate.inl"
#endif

#ifndef EXTERNAL_TEMPLATE_DEFINITION
#include "MyTemplate.cpp"
#endif

// MyTemplate.cpp
// MyTemplate <T> non-inline implementation file
#ifdef EXTERNAL_TEMPLATE_DEFINITION
#include "MyTemplate.h"
#endif

// MyTemplate <T> non-inline method implementation...

#ifdef DISABLE_INLINE
#include "MyTemplate.inl"
#endif

// MyTemplate.inl
// MyTemplate <T> inline implementation file
#ifdef DISABLE_INLINE
#define inline
#endif

// MyTemplate <T> inline method implementation, including the 'inline'
keyword ...

#ifdef DISABLE_INLINE
#undef inline
#endif

I use this scheme for both template and non-template classes. Template
method definitions are really included inside header file while remain
physically in a separate file. So this is not a problem.


andre dajd
Guest
 
Posts: n/a
#4: Jul 22 '05

re: Types defined inside templates



"Ruben Campos" <Ruben.Campos@robotica.uv.es> wrote in message
news:cmfes5$b9g$1@peque.uv.es...[color=blue]
> I've found a problem with types defined inside a template. With a
> non-template class, I can write the following:[/color]
[snip]

First, there are no "source" files for the templates. You will have to
include both template class declaration and definition in where you are
going to instantiate them. Usually you do it either by having a mega
header, or one "master" header that pulls up other files. Eg the master
could contain class declaration and it's last line could have #include of a
cpp "source" looking like file that contains definitions.
[color=blue]
> Well, my problem is that this don't work with templates:
>
> // MyTemplate.hpp
> template <typename T>
> class MyTemplate
> {
> // ...
> typedef unsigned int MyType;
> MyType MyMethod ( /* ... */ );
> // ...
> };
>
> // MyTemplate.cpp
> template <typename T>
> MyTemplate <T>::MyType
> MyTemplate <T>::MyMethod ( /* ... */ )
> {
> // ...
> }
>[/color]

This is wrong. You must identify MyType as a type with "typename":

template <typename T>
typename MyTemplate <T>::MyType
MyTemplate <T>::MyMethod ( /* ... */ )
{
// ...
}

With this addition I could compile your code in VS2003

Note that VC6 implements so called "implicit typename", that does not
require you use "typename" in the above example, but it will be an error in
all better standard complying compliers (.net, gnu).

Rgds
ad



Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com
Closed Thread