[Q] Deriving from templates

E

Eric

I've got a fairly simple setup that I thought would work, but I am
getting link errors.


template <class T>
class TType
{
public:
TType( void ) {}
virtual ~TType( void ) {}
virtual void Release( void ) {}
virtual void Retain( void ) {}
protected:
T mRef;
private:
};


template <class T>
class TTree :
public TType<T>
{
public:
TTree( void ) {}
virtual ~TTree( void ) {}
protected:
private:
};


class CTree :
public TTree<long>
{
public:
CTree( void ) {}
virtual ~CTree( void ) {}
Boolean Create( void ) { Release(); return false; }
protected:
private:
};


Elsewhere, I say:

CTree myTree;

Everything compiles, but the link errors I get claim that everything
from the TType class is undefined.

Any ideas?
 
E

Eric

Victor Bazarov said:
Have you tried the FAQ?

Yes. Unfortunately, it isn't helping much. I have a hard time clicking
my heels twice and thinking of Kansas - at least 34.13 seems to be the
most applicable section in this case.

Of course, what also may not be helping is that what I posted will
compile and link - attempted a short cut that I neglected to test first.

So, it needs to be changed to:

(This code, again, tells me that everything in TType is not defined.)

// TType.h
// TType.h
// TType.h

emplate <class T>
class TType
{
public:
TType( void );
virtual ~TType( void );
virtual void Release( void );
virtual void Retain( void );
protected:
T mRef;
private:
};

// TType.cp
// TType.cp
// TType.cp

template <class T>
TType<T>::
TType( void )
{
mRef = NULL;
}
template <class T>
TType<T>::
~TType( void )
{
}
template <class T>
void
TType<T>::
Release( void )
{
}
template <class T>
void
TType<T>::
Retain( void )
{
}

// TTree.h
// TTree.h
// TTree.h

template <class T>
class TTree :
public TType<T>
{
public:
TTree( void ) {}
virtual ~TTree( void ) {}
protected:
private:
};


class CTree :
public TTree<long>
{
public:
CTree( void ) {}
virtual ~CTree( void ) {}
Boolean Create( void ) { Release(); return false; }
protected:
private:
};
 
V

Victor Bazarov

Eric said:
Yes. Unfortunately, it isn't helping much. I have a hard time clicking
my heels twice and thinking of Kansas - at least 34.13 seems to be the
most applicable section in this case.

No, 34.14 does.
Of course, what also may not be helping is that what I posted will
compile and link - attempted a short cut that I neglected to test first.

So, it needs to be changed to:
[...]
 
V

Victor Bazarov

Eric said:
It was a typo. I meant to say 34.14.

Unfortunately, it still isn't helping much.

Much?

There are three solutions suggested in 34.14. Which one have you tried
and how don't they help?
 
E

Eric

Eric said:
It was a typo. I meant to say 34.14.

Unfortunately, it still isn't helping much.

For example, when I attempt to place:

template TType<long>;

at the end of TType.cp (similar to 34.14's Foo.cpp), I get a compile
error. (illegal explicit template instantiation).

Please note, my case is at least a bit different from the one in 34.14.
In my case, I have a class derived from a template derived from a
template. In the case of 34.14, it is simply a direct use of the
template itself.

It is unclear to me why this should make much difference, but perhaps it
does.
 
V

Victor Bazarov

Eric said:
For example, when I attempt to place:

template TType<long>;

at the end of TType.cp (similar to 34.14's Foo.cpp), I get a compile
error. (illegal explicit template instantiation).

Could it be that your compiler is somehow buggy in that area? What
compiler are you using?
Please note, my case is at least a bit different from the one in 34.14.
In my case, I have a class derived from a template derived from a
template. In the case of 34.14, it is simply a direct use of the
template itself.

It is unclear to me why this should make much difference, but perhaps it
does.

Is TType a template? If so, an explicit instantiation of it is allowed.

Anyway, try other solutions.

V
 
E

Eric

Victor Bazarov said:
Eric said:
It was a typo. I meant to say 34.14.

Unfortunately, it still isn't helping much.

Much?

There are three solutions suggested in 34.14. Which one have you tried
and how don't they help?


I already mentioned that I tried the first one (stick everything into a
single header file) and can apparently get it to work, but this solution
will not, in the end, be a practical one.

In a message you are may be reading as I write this, I tried the second
one (place the equivalent of template Foo<int>; into the equivalent of
Foo.cpp) and am getting a compile time error.

I have not attempted the third, but I suspect it will be of no help
either, since, as the FAQ seems to indicate, the second and third
solutions are virtually equivalent.
 
E

Eric

Victor Bazarov said:
Could it be that your compiler is somehow buggy in that area?

Extremely unlikely.
What compiler are you using?

Latest Codewarrior for MacOSX.

However, when I changed that code to:

template class TType<long>;

It does compile. I am guessing this is a misunderstanding of the FAQ
answer on my part rather then an error in the FAQ.

I am reading the FAQ found at:

<http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq
-34.12>

(I scrolled down from 34.12)
Is TType a template?

I posted earlier:

// TType.h
// TType.h
// TType.h

template <class T>
class TType
{
public:
TType( void );
virtual ~TType( void );
virtual void Release( void );
virtual void Retain( void );
protected:
T mRef;
private:
};

// TType.cp
// TType.cp
// TType.cp

template <class T>
TType<T>::
TType( void )
{
mRef = NULL;
}
template <class T>
TType<T>::
~TType( void )
{
}
template <class T>
void
TType<T>::
Release( void )
{
}
template <class T>
void
TType<T>::
Retain( void )
{
}
If so, an explicit instantiation of it is allowed.

I do not doubt that it should be.
Anyway, try other solutions.

Have. Don't work or not practical.

Solution #1 not practical.
Solution #2 still claims undefined for everything in TType.
Solution #3 gives multiply-defined link errors.

And then, I should mention the final part:

// Random.cp
// Random.cp
// Random.cp

#include "TTree.h"

void AFunction ( void )
{
CTree myTree;
}


So, how would you modify TType.h, TType.cp, TTree.h & Random.cp?
 
V

Victor Bazarov

Eric said:
Extremely unlikely.




Latest Codewarrior for MacOSX.

However, when I changed that code to:

template class TType<long>;

It does compile. I am guessing this is a misunderstanding of the FAQ
answer on my part rather then an error in the FAQ.

I am reading the FAQ found at:

<http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq
-34.12>

(I scrolled down from 34.12)




I posted earlier:

// TType.h
// TType.h
// TType.h

template <class T>
class TType
{
public:
TType( void );
virtual ~TType( void );
virtual void Release( void );
virtual void Retain( void );
protected:
T mRef;
private:
};

// TType.cp
// TType.cp
// TType.cp

Uh... Where is

#include "TType.h"

??
template <class T>
TType<T>::
TType( void )
{
mRef = NULL;
}
template <class T>
TType<T>::
~TType( void )
{
}
template <class T>
void
TType<T>::
Release( void )
{
}
template <class T>
void
TType<T>::
Retain( void )
{
}




I do not doubt that it should be.




Have. Don't work or not practical.

Solution #1 not practical.
Solution #2 still claims undefined for everything in TType.
Solution #3 gives multiply-defined link errors.

And then, I should mention the final part:

// Random.cp
// Random.cp
// Random.cp

#include "TTree.h"

void AFunction ( void )
{
CTree myTree;
}


So, how would you modify TType.h, TType.cp, TTree.h & Random.cp?

I don't know. I can't say I believe I actually have seen them as they
are intended to be or are in your project.

V
 
E

Eric

Uh... Where is

#include "TType.h"

??

oops. It's actually there. Copy/Paste mistake.
I don't know. I can't say I believe I actually have seen them as they
are intended to be or are in your project.

Ok. Hopefully someone else will know.
 
J

Jonathan Mcdougall

Eric said:
There are three solutions suggested in 34.14. Which one have you tried
and how don't they help?



I already mentioned that I tried the first one (stick everything into a
single header file) and can apparently get it to work, but this solution
will not, in the end, be a practical one.


Unfortunately, that is how most modern compilers
work. I think only Comeau implements the export
keyword, but you may have a look at your
compiler's documentation.
In a message you are may be reading as I write this, I tried the second
one (place the equivalent of template Foo<int>; into the equivalent of
Foo.cpp) and am getting a compile time error.

The correct syntax is

template class Foo<int>;

Is that an error in the FAQ?
I have not attempted the third, but I suspect it will be of no help
either, since, as the FAQ seems to indicate, the second and third
solutions are virtually equivalent.

The third is only a workaround for the second.

I would suggest to include the function's body in
the class' definition (in the header). I
understand it may not be the best design you saw,
but it is the only one that works reliably.


Jonathan
 
E

Eric

Jonathan Mcdougall said:
Eric said:
There are three solutions suggested in 34.14. Which one have you tried
and how don't they help?



I already mentioned that I tried the first one (stick everything into a
single header file) and can apparently get it to work, but this solution
will not, in the end, be a practical one.


Unfortunately, that is how most modern compilers
work. I think only Comeau implements the export
keyword, but you may have a look at your
compiler's documentation.


Huh.

Well, my case will ultimately involve a lot of classes (20+) & several
thousand lines of code. I really wanted a better organization for this
and not be forced to stick everything into a single and probably nearly
unmanageable header file.

I'm still hoping someone will have a hint on how to do what I want to
do.
 
O

Old Wolf

Eric said:
Well, my case will ultimately involve a lot of classes (20+) &
several thousand lines of code.

It worked for the Standard C++ Library, why can't it work for you?
I really wanted a better organization for this and not be forced
to stick everything into a single and probably nearly
unmanageable header file.

Use many header files, then. Model your organization on
an STL implementation that you like.

Also, you only have to put code that depends on the template
parameter into the header file -- eg. your CTree class can
go in a non-header.
 
J

Julie

Old said:
It worked for the Standard C++ Library, why can't it work for you?




Use many header files, then. Model your organization on
an STL implementation that you like.

Also, you only have to put code that depends on the template
parameter into the header file -- eg. your CTree class can
go in a non-header.

I'd hardly call the STL portions a model of how to do things. No offense to
PJP, et al., but I consider the STL a _horrible_ mess of virtually unreadable code.
 
V

Victor Bazarov

Julie said:
[...]
I'd hardly call the STL portions a model of how to do things. No
offense to PJP, et al., but I consider the STL a _horrible_ mess of
virtually unreadable code.

I am fairly certain it's perfectly readable to those who wrote it.
It is possible that they use an automated obfuscator before shipping
the final result, of course.

Besides, Mike didn't suggest to use Dinkumware's version _specifically_
but "an STL implementation that you like". If you don't like any [you
have seen], it doesn't mean they all are bad.

V
 
J

Julie

Victor said:
Julie said:
[...]
I'd hardly call the STL portions a model of how to do things. No
offense to PJP, et al., but I consider the STL a _horrible_ mess of
virtually unreadable code.


I am fairly certain it's perfectly readable to those who wrote it.

Probably. And for the rest of us?
It is possible that they use an automated obfuscator before shipping
the final result, of course.

Yes, possible, but if the case, of very detrimental value.

Forget the code, of all the STL documentation that I've seen, it is based on
that (deliberately or consequentially) obfuscated code. Personally, I rate STL
documentation as the worst there is, but I digress...
Besides, Mike didn't suggest to use Dinkumware's version _specifically_
but "an STL implementation that you like". If you don't like any [you
have seen], it doesn't mean they all are bad.

I'll readily admit that I'm far from an STL expert and have limited exposure to
: Borland's version (from the early days), whatever has shipped w/ MS VisualC++
(Dinkumware included), and SGI. None of those qualify as readable to me.

If you have any recommendations to _any_ implementation that is written w/
/clarity/ in mind, please let me know, same applies to documentation.

If anyone cares, and I doubt that anyone does, those are the *main* reasons
that I don't spend a lot of time w/ STL. I didn't grow up on Unix, and
personally, shun that style and level of obfuscation.
 

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

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top