Reputation: 295
I was wondering if there are pattern/ways to inherit template functions ? Template functions can not be virtual so if my base class has a template function and my derived class has the same, the function of the base class will always be called in the following example :
struct Base {
Base() {}
template < typename T >
void do_something(T& t) const {
t << "Base" << std::endl ;
}
};
struct Foo : Base {
Foo() : Base () {}
template < typename T >
void do_something(T& t) const {
t << "Foo" << std::endl ;
}
};
struct Bar : Foo {
Bar() : Foo() {}
template < typename T >
void do_something(T& t) const {
t << "Bar" << std::endl ;
}
};
int main(int argc, char** argv)
{
Base *b = new Base() ;
Base *f = new Foo() ;
Base *ba = new Bar() ;
b->do_something(std::cout) ;
f->do_something(std::cout) ;
ba->do_something(std::cout) ;
return 0 ;
}
So this program always print :
Base
Base
Base
Is there a way to make my program print :
Base
Foo
Bar
Actually the only way I found for doing that is to make a static_cast :
...
static_cast<Foo*>(f)->do_something(std::cout) ;
static_cast<Bar*>(ba)->do_something(std::cout) ;
...
Is there any pattern or elegant way to encapsulate the cast so that it will be unnoticeable from the function call ? Thanks for your replies
Upvotes: 6
Views: 7449
Reputation: 589
Do you have the option to change the struct to a Template class rather than template methods?
If so:
Template<typename T>
struct Base
{
public:
virtual void doSomething();
};
Template<typename T>
struct Foo : Base<T>
{
public:
virtual void doSomething();
};
Upvotes: 1
Reputation: 72271
You can almost always do what you need by splitting the function into smaller parts, making each part templated if necessary, or virtual if necessary. In this example, that's as simple as:
struct Base {
Base() {}
template < typename T >
void do_something(T& t) const {
t << something_piece() << std::endl ;
}
virtual const char* something_piece() const {
return "Base";
}
};
struct Foo : Base {
Foo() : Base () {}
const char* something_piece() const {
return "Foo";
}
};
struct Bar : Foo {
Bar() : Foo() {}
const char* something_piece() const {
return "Bar";
}
};
It can get more complicated than that, but the idea is pretty powerful at combining compile-time and run-time differences.
Upvotes: 4