Skip to main content
GameDev.net gamedev.net
🔒 Locked

partial template specialisation problem

Started by Hybrid666 Apr 13, 2009 at 4:56 AM 6 replies 1.1k views
Original Post
Hybrid666
Hybrid666
Hi, I'm trying to find a nice way to implement a string class that is based on an array class.. currently i have this working:

template<sint32 MaxLength>
class tString : public tArray<char, MaxLength>


However, I don't really want my string class using inheritance like this, I'd rather it used template specialisation, but I can't figure out a nice way of doing it :( The closest I've gotten is using a typedef embedded in a class, but that leaves me having to say:

tString<64>::Type Variable;


Ideally I just want to be using something like:

tString<64> Variable;


Has anyone found a way of achieving this? Am i missing something obvious? I've considered using a #define for it.. which would leave me with:

#define tString(MaxLength) tArray<char, MaxLength>
tString(64) Variable;


I suppose that's ok.. but I don't like it much.. :) Thanks for any help, Hybrid
rip-off
rip-off
I would be partial to using simple composition in such a scenario. Well, in truth I would use std::string, but aside from that for the moment.
template<int N>class tString{public:    // ...private:    tArray<char, N> storage;};

This allows you to minimise the interface to what you want. I believe you can do similar things with template specialisation, but IMO the extra complexity isn't worth it.
Hybrid666
Hybrid666
Ha, yeah std::string is good, but my problem applies to other non-string related problems :)

In your example, surely I then have to pass through a lot of tArray functionality in the string class, e.g. the [] operator, GetSize() function, etc etc ?

or use the string by making calls to a GetStorage() member in a lot of places?

I don't think C++ has a nice solution to offer me for this problem :(
NotAYakk
NotAYakk
Quote:
However, I don't really want my string class using inheritance like this, I'd rather it used template specialisation, but I can't figure out a nice way of doing it :(

May I ask why?

Template typedefs are coming in C++0x.

Before that point, barring the operators that you lose (operator= and constructors), inheritance is pretty close.

There are some quirky differences in the world of type overloading vs template specialisation... But they are relative corner cases. (Template specialisation doesn't 'know about' C++ object type hierarchies, which can cause some problems in a few corner cases.)
Hybrid666
Hybrid666
Hmmm... this is a good question, and has just prompted me to do some googling, because I was thinking the inheritance approach would incur some extra function call overhead due to vtable lookups etc.. but because none of the functions I am using are overriden virtuals, I don't think there is any runtime penalty for using inheritance?

Google seems to corroborate this theory..

is there any runtime penalty for using the inheritance approach, if I'm only using the dervied class for adding extra functionality, not for overriding base class functionality?
rip-off
rip-off
C++ tries as hard as it can to make decisions at compile time, not runtime. With no virtual functions, you won't pay for using inheritance. But be warned, inheritance can cause problems. For example, the following code will not work:
template<sint32 MaxLength>class tString : public tArray<char, MaxLength>{};int main(){    tArray<char, 100> *array = new tString<100>();    delete array;};

To make it work, the destructor in tArray needs to be virtual, which will cause a virtual dispatch anywhere you delete a pointer to a tArray (or derived) class.

Remember, using inheritance ties you to the tArray class, whereas using composition makes it easier to move away from this dependency (e.g. to boost::array).

But I still think it is odd that you worry about virtual function cost when you potentially are instantiating lots of classes for each value of MaxLength, which may be unable to share code and thus could increase the size of your executable, which is another cost. You are making a trade off here, both in terms of performance (though I am not going to guess as to which would be faster) and in usability.

To be honest, unless I had a compelling reason not to I would just use std::vector<> for arrays and std::string for text.
Hybrid666
Hybrid666
ok,

thanks for the help :)
NotAYakk
NotAYakk
Quote:
To make it work, the destructor in tArray needs to be virtual, which will cause a virtual dispatch anywhere you delete a pointer to a tArray (or derived) class.

*nod*, except you are also getting a heap deallocation hit.

The cost of that will probably hide the cost of the virtual pointer lookup.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.