Types defined inside templates

R

Ruben Campos

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 :)
 
K

Karthik Kumar

Ruben said:
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 ( /* ... */ )
{
// ...
}

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).
 
R

Ruben Campos

Karthik Kumar said:
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).

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.
 
A

andre dajd

Ruben Campos said:
I've found a problem with types defined inside a template. With a
non-template class, I can write the following:
[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.
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 ( /* ... */ )
{
// ...
}

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top