class specialisation global template inheritance

Started by
6 comments, last by ProPuke 18 years, 11 months ago
Okay guys, time to get your hands dirty Who here can help me get around this little prob? I warn ya, this is some heavy shizz I've got a base templated structure like this:
template<typename Type>
struct Structure{
	/* contents... */
};
Now I want to offer a specialisation for that class for pointer types... BUT the original class is damn big; So I want this new one to inherit all of its contents...
template<typename Type>
struct Structure<Type*>:Structure<Type*>{
	/* extra contents... */
};
Well that's no good coz it links back to itself (since Type* is already specialised). What I'm after is a way of passing Type* as the the type for the original global templation without getting a feedback loop My first plan was to add a boolean flag to the original global template with a default value of true & use that to differentiate:
template<typename Type, bool original=true>
struct Structure{};

template<typename Type>
struct Structure<Type,true>{
	/* contents... */
};

template<typename Type>
struct Structure<Type*,false>:Structure<Type*,true>{
	/* extra contents... */
};
BUT quite a few of the methods in the global prototype <Type,true> return instances of itself. That means the return type for those functions MUST contain all template parameters. But I can't cast to <Type,true> because then those methods will cast when inherited by the pointer alternative & the results won't have the extra contents So really the global template version MUST be able to fully contain the specialisation, but if this is the case then how do I differentiate that I want to inherit from the base without the inherit line being picked up by the specilisation itself.. I doubt there is special syntax for this I know c++ templating is severly limited & I'm already right up against the limits in several other situations. But does anyone know a way around this? Maybe some other way of copying the declaration body from the first to the specilisation using macros? & then somehow linking in their later definitions.. oh I don't know This is a CHALLENGE, comon you great minds out there! (& yeah it's g++ 8P)
_______________________________ ________ _____ ___ __ _`By offloading cognitive load to the computer, programmers are able to design more elegant systems' - Unununium OS regarding Python
Advertisement
any chance you could move some of the internals to a base and then derive the template and the specialisation from that?
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
I thought about that, but the specialisation actually overrides a few of the originals methods & the original methods must be able to access the new overrides - So I can't push them into a subclass
_______________________________ ________ _____ ___ __ _`By offloading cognitive load to the computer, programmers are able to design more elegant systems' - Unununium OS regarding Python
Maybe I won't be making much sense as I'm not an expert at template programming, but in the same way ChaosEngine suggested, why don't you do something like this:

template<typename T>
base_structure
{
// contains everything you want in your base
};

template<typename T>
structure<T> : base_structure<T>
{
// define nothing in here
};

template<typename T>
structure<T*> : base_structure<T*>
{
// redefine needed methods here
};

Hmmm... I'm not sure about this, but anyway, it's the only thing I can think of.

EDIT

I re-read your post and I see what you mean. However, from what I know of C++, what you ask is impossible by standard means. Because you want the functionality of the "virtual" keyword and templates at the same time, I think that's not normally possible.

struct Structure
{
virtual void do() { cout << "Base" << endl; }
void do_it() { do(); }
};

struct Derived : public Structure
{
virtual void do() { cout << "derived" << endl; }
};

Excuse syntax errors if there are any. Calling do_it() from a Structure or from a Derived won't do the same thing, that's what you mean, but that's only possible with polymorphism, but I think it cannot be mixed with templates. But I may be wrong.

From what I read, partial specialization involves re-writing the whole class/structure and that's it, there's no shortcut.

Correct me somebody if I'm wrong :)
Well originally the reason I didn't do that was because base_structure's methods need to intergrate with structure's methods & members
I suppose this could be acomplished through a parent pointer specified in base_structure's constructor, & thinking about it now - it does feel like an alternative
The structure itself would also need to be aware of when its address changes so that it could update it's base_structure child accordingly. But this is actually already implemented in my framework so it is fully possible
It is a messy alternative though & I'm still open to single class alternatives

RESPONSE TO EDIT

virtual methods can be used in templated classes as long as the methods themselves being made virtual do not have their own templates

Quote:From what I read, partial specialization involves re-writing the whole class/structure and that's it, there's no shortcut

Actually it does appear you can cross inherit from other specialisations during declaration & that's what I was trying to do. The problem is finding a way to inherit from a template instance that fully contains the specialisation
it might be possible.. we'll see ;]

But thanks you were right with your suggestion, & yours & ChaosEngine's post are more feasible than first thought
_______________________________ ________ _____ ___ __ _`By offloading cognitive load to the computer, programmers are able to design more elegant systems' - Unununium OS regarding Python
Sorry, didn't have time to analyse your problem fully, but would the following volatile hack work? (You could do it with const instead of volatile, but I guessed that volatile would be less intrusive - it does however mean that you can't actually template the class on a volatile type)
#include <iostream>template < typename TYPE >class NonVolatile{	public:		typedef TYPE type;};template < typename TYPE >class NonVolatile< TYPE volatile >{	public:		typedef TYPE type;};template < typename TYPE >class Test{	private:		typedef NonVolatile< TYPE >::type Type;	public:		virtual Type function1(Type t)		{			std::cout << "base Test function1\n";		}		Type function2(Type t)		{			std::cout << "base Test function2\n";		}};template < typename TYPE >class Test< TYPE * >	:	public Test< TYPE * volatile >{	public:		virtual TYPE * function1(TYPE * t)		{			std::cout << "specialised Test function1\n";		}};int main(){	Test< int > intTest;	Test< int * > intPointerTest;	int i = 7;	intTest.function1(i);	intTest.function2(i);	intPointerTest.function1(&i);	intPointerTest.function2(&i);}


Enigma
Quote:Original post by ProPuke
I know c++ templating is severly limited & I'm already right up against the limits in several other situations.


Have your read these before:

Modern C++ Design: Generic Programming and Design Patterns Applied
C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond

I'm pretty sure you wouldn't say that if you did already [smile]

Anyways back to the problem, you want to do something different when a certain type is given in this case all pointer types without resorting to partial specializations. Do you know about type traits, type/tag dispatching?

If you could give more details on exactly what you want to do if a pointer type is given, i'll try and show you how to achieve this, but basically you want is a is_pointer type traits then conditionally dispatch on type at compile-time, is_pointer is trival to define:

template < typename Tp >struct is_pointer { static const bool val = false; };template < typename Tp >struct is_pointer<Tp*> { static const bool val = true; };


but there is no need to reinvent the wheel, boost has a whole type traits and template metaprogramming library at your disposal
Hugs & kisses for snk_kid!

I forgot all about those nifty type dispatching methods. I guess sometimes you've gotta just keep relearning over & over again until it sticks
Gamedev never ceases to open my mind in new ways & I think that's largely to blame on you snk_kid if I am not mistaken
Well you best stop helping me now, as I can no longer rate you any higher :P
(soz that it's had no affect on your rating, guess I must of been a much lower level when I rated you before, suxors :/)

Well suffice to say that took me in precisely the right direction to sorting that all out

Enigma: Your hack might work but it makes me feel all dirty inside

thankyou all for taking the time ;]
_______________________________ ________ _____ ___ __ _`By offloading cognitive load to the computer, programmers are able to design more elegant systems' - Unununium OS regarding Python

This topic is closed to new replies.

Advertisement