templates and local types

C

Christof Warlich

Hi,

Consider:

template<typename T> class Z {};
int doSomething(void) {
class X {};
Z<X> z;
}

Any idea how this can be made compilable while keeping class X local?

The example has been simplified significantly. The reason why class X
has to be local is because doSomething() is a template function and
class X needs to be instantiated with the same type as doSomething().

Thanks for any help,

Christof
 
J

John Carson

Christof Warlich said:
Hi,

Consider:

template<typename T> class Z {};
int doSomething(void) {
class X {};
Z<X> z;
}

Any idea how this can be made compilable while keeping class X local?

The example has been simplified significantly. The reason why class X
has to be local is because doSomething() is a template function and
class X needs to be instantiated with the same type as doSomething().

In that case you have simplified the problem to the point of removing
essential features. I take it that doSomething and X are both templates.
Then what is wrong with:

template<typename T> class Z {};

template<typename T> class X {};

template<typename T>
int doSomething(void)
{
Z< X<T> > z;
return 0;
}
 
C

Christof Warlich

John said:
In that case you have simplified the problem to the point of removing
essential features. I take it that doSomething and X are both templates.
Then what is wrong with:

template<typename T> class Z {};

template<typename T> class X {};

template<typename T>
int doSomething(void)
{
Z< X<T> > z;
return 0;
}
You are right, I've probably stripped down things too much. But some
additional explanations may do:

My intention was to separate template declaration and definition (See
FAQ Lite: How can I avoid linker errors with my template functions).
Doing this, I wanted to minimize the lines of code that have to be
written to explicitly instantiate my templates (in this simple case,
just instantiating doSomething() for the required types instead of
having to instantiate doSomething() and class X).
 
J

John Carson

Christof Warlich said:
You are right, I've probably stripped down things too much. But some
additional explanations may do:

My intention was to separate template declaration and definition (See
FAQ Lite: How can I avoid linker errors with my template functions).
Doing this, I wanted to minimize the lines of code that have to be
written to explicitly instantiate my templates (in this simple case,
just instantiating doSomething() for the required types instead of
having to instantiate doSomething() and class X).


You could turn your function into a functor, like std::cout. To get this to
work of course, you need to declare an object of the class, either (i) in
client code or (ii) in the implementation file, with an extern declaration
in the header. This gives an extra line (or two), so you may not think this
approach offers an advantage --- though it still could if you had classes A,
B, C... as well as X.

First, a version where it all goes in the header:

template<typename T>
class Z {};

template<typename T>
class doSomething
{
class X {};
public:
int operator()()
{
Z<X> z;
return 0;
}
};

// need to also declare an object of the class


Splitting this into .h and .cpp files, we would have:

////// foo.h file ///////////////////////////

template<typename T>
class doSomething
{
class X;
public:
int operator()();
};

extern doSomething<int> ds;


/////// foo.cpp file //////////////////////

#include "foo.h"

template<typename T>
class Z {};

template<typename T>
class doSomething<T>::X
{};

template<typename T>
int doSomething<T>::eek:perator()()
{
Z<X> z;
return 0;
}

// only one instantiation line required
template class doSomething<int>;

// but need this line unless client code has it
doSomething<int> ds;

//////// main.cpp file /////////////////////

#include "foo.h"

int main()
{
ds();
}

/////////// end files ///////////////////////

The above seems to work with VC++ 2005.
 
R

Ron Natalie

Christof said:
Hi,

Consider:

template<typename T> class Z {};
int doSomething(void) {
class X {};
Z<X> z;
}

Any idea how this can be made compilable while keeping class X local?
Can't be done. You can move doSomething and X into a namespace,
but templates can't have local types.
 
C

Christof Warlich

John said:
You could turn your function into a functor, like std::cout. To get this to
work of course, you need to declare an object of the class, either (i) in
client code or (ii) in the implementation file, with an extern declaration
in the header. This gives an extra line (or two), so you may not think this
approach offers an advantage --- though it still could if you had classes A,
B, C... as well as X.
Hi John,

thanks a lot, that's an interesting approach. I'll go and play around
with it today. But anyhow, I realized that I reached my goal also with
your very first suggestion: It was sufficient to instantiate doSomething
even when class X was not local; class X seems then to be instantiated
as well.

Regards,

Christof
 

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

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top