简体   繁体   中英

Inheritance and template function c++

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

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.

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();
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM