Forcing template parameter type

Oldtimer
Posts: 834
Joined: 2002.09
Post: #1
I guess this might be a degenerate case of template specialization, but I wanted to see if anyone has an inkling of a good way through this...

The problem is that I have a template parameter for a function, and I'd like to require that the template parameter is a subclass of another specific type.

I'm rewriting my asset manager using templates. I used to work with a fixed set of assets, derived from the base class BaseAsset. Specific assets were loaded through a slew of functions named bmLoadTexture, bmLoadStreamedSound, bmLoadFont...

I have a working templatized function bmLoad now which instantiates based on a pointer:
Code:
template <class T>
bmError bmLoad (bmString filePath, T* &assetPtr)
{
}

If I call this function with a bmTexture as the second parameter, all is well. The problem is, it's very possible to call this with something that isn't a BaseAsset subclass, for instance a float* will do just fine. Deep down inside these templatized functions there's a reinterpret_cast from the given pointer type to the BaseAsset type (which is there for header inclusion reasons). This reinterpret cast can happily take the float pointer above, assume it is a BaseAsset, call a method on it and end up in La-La land.

That's the problem, and while it is a minor issue, I'd like to ask if there's a way to somehow force the compiler to only accept BaseAsset subclasses for its template parameter?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
Boost, inevitably, knows how:

http://www.boost.org/doc/html/boost_type...is_base_of

I, however, don't understand it Wink
Quote this message in a reply
Member
Posts: 72
Joined: 2006.10
Post: #3
A very quick and dirty way to do this would be to have baseclass contain something like this:

Code:
class BaseAsset {
public:
    void BogusBaseAssetConfirmationFunction() {}
} ;

template <class T>
bmError bmLoad (bmString filePath, T* &assetPtr)
{
   ...
   assetPtr->BogusBaseAssetConfirmationFunction() ;
   ...
}
The BogusBaseAssetFunction() call will get optimized out of the binary code (since it's an empty inline function), and any type passed in that function that does not have it implemented will cause a compiler error.

At this point, you lose the advantage of a template, and you might as well just use polymorphism, but it does force the compiler to only accept BaseAsset subclasses.
Quote this message in a reply
Oldtimer
Posts: 834
Joined: 2002.09
Post: #4
Wow, Boost never seizes to boggle my mind...
Sohta, that was a very clever trick that almost had me going for it, but I walked away from the problem for an hour and beat myself with the Stick of Obviousness+1.

Code:
if (dynamic_cast<BaseAsset*>(assetPtr) == NULL)
    Log (PANIC, "Tried to load asset that was not a BaseAsset subclass!");

I already have RTTI turned on for exception handling, so it isn't even an impact...
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #5
OneSadCookie Wrote:Boost, inevitably, knows how:

http://www.boost.org/doc/html/boost_type...is_base_of

I, however, don't understand it Wink

That's the problem with real C++, and boost in general. I've done some nice C++ templating malarky in the past, and while it worked it was pretty narrow in functionality. Then I started using Boost.Python and realized parts of it did what I was trying to do, but better. When I tried to understand how Boost did it, I went crosseyed.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Using a Class name as a parameter...? SamBaylus 9 4,519 Feb 2, 2010 04:34 AM
Last Post: SamBaylus
  C++ template problem anthony 9 5,735 Feb 7, 2007 10:04 AM
Last Post: anthony