views:

86

answers:

2

I want to be able to define

template <class TX>
void f(const TX &x){ ... }
template <class TY>
void f(const TY &x){ ... }

where TX must be derived from BaseX and TY must be derived from BaseY (how do I specify this kind of thing?), and I want to be able to call it as

f(DerivedX<T>())

It is most important that I can avoid specifying the template parameters. Is this possible, and if so how would I implement it? If it's not possible, is there a way I can make a templated function accept only certain types, but still have it be implicitly instantiated? I cannot just make the overloads of f accept the base class because I need the derived class' type.

A: 
template <class TX>
void f(const BaseX &x){ ... }
template <class TY>
void f(const BaseY &x){ ... }

f<DerivedX>(DerviedX<T>())

That seems easiest to me. You could use boost's is_base_of if you don't want to supply the explicit template argument.

wrang-wrang
Nice. First answer w/ is_base_of, and -1.
wrang-wrang
+5  A: 

You can use is_base_of from Boost.TypeTraits like so:

#include <boost/type_traits.hpp>
#include <boost/utility.hpp>

class BaseX { };
class BaseY { };

class DerivedX : public BaseX { };
class DerivedY : public BaseY { };

template <typename TX>
boost::enable_if<boost::is_base_of<BaseX, TX>, void>::type
f(const TX& x) 
{
}

int main(int argc, char** argv)
{
    DerivedX x;
    DerivedY y;

    f(x); // compiles
    f(y); // will cause a compilation error
}

The Boost.TypeTraits library is header-only, so you don't need to link anything in.

James McNellis
An addendum - what enable_if does is it only has a `type` member if the condition is true, so it causes a compile error if you try to use `type` and the condition is false. However, because of a principle known as SFINAE (substitution failure is not an error), that just tells the compiler not to pick that version of the template. If you have another one for `BaseY`, the compiler will fail to create one of the two templates, and be forced to use the other. Since it will be the only eligible template, it will be selected.
coppro
Ok, I read about those, and they seem to be what I'm after. The code you listed however, does not compile.
Victor Liu
Sorry, that was a copy-and-paste failure; try again (I removed the extra `void` from the definition of `f`). It should now compile (if you remove the line `f(y);`, since its purpose is to demonstrate what would cause a compiler error).
James McNellis