I've got a template class:
template <class T>
class TemplateClass
{
//irrelevant what this class does
}
And two classes, one base and one class which derives from it:
class Base
{
//does whatever
}
cl开发者_运维知识库ass Derived : public Base
{
}
Now I want to assemble a function which can deal with TemplateClass of templated type Base* as well as TemplateClass of templated type Derived* without having to implement the function separately for both types.
In code, this is what I'd like to be able to do:
void DoSomething(const TemplateClass<Base *> &tc)
{
//do something
}
And somewhere else in the code:
TemplateClass<Base *> a;
TemplateClass<Derived *> b;
DoSomething(a); //Works
DoSomething(b); //Doesn't work, but I'd like it to work
Is there a way to implement this without having to manualy overload DoSomething for Derived* ?
Sadly, C++ does not support template covariance, so you cannot do that automatically. As a workaround, you could do something like this:
template <typename T>
void DoSomething(const TemplateClass<T*>& tc) {
// in C++03, use BOOST_STATIC_ASSERT and boost::is_convertible
static_assert(
std::is_convertible<T*, Base*>::value,
"Template argument must be convertible to Base*"
);
// ...
}
Demo on ideone.
It is simple to solve this if you are not opposed to a more general situation:
I would simply add a template parameter to your DoSomething
function:
template<class T>
void DoSomething(const TemplateClass<T *> &tc)
{
}
Of course, this doesn't allow you to directly constrain the parameter T
to being a subclass of Base
. But it will allow you to not write several overloads of DoSomething
.
Edit
If your TemplateClass
was intended to wrap a value of type T
, then there may be a way to constrain to parameter for DoSomething
.
Suppose TemplateClass
were declared something like
template<class T>
class TemplateClass
{
public:
TemplateClass( T value )
: Value(value)
{
}
T Value;
};
Then DoSomething
could be written as
template<class T>
void DoSomething( const TemplateClass<T *> &tc )
{
Base * b = tc.Value;
}
Now, during compilation, the line Base * b = tc.Value
will only compile if T
is set to a subclass of Base
. Otherwise, it will fail due to an invalid conversion.
Of course, this is a very simple example which may ignore some elements of good design. But the principle is there, and this is the only way I am currently aware of the produce such a constraint on a template parameter.
精彩评论