Can I use CRTP with multiple derived classes, and use them polymorphically?

user1289

I have such hierarchy of classes:

template <class Type>
class CrtpBase
{
protected:
    Type& real_this()
    {
        return static_cast<Type&>(*this);
    }
};

template <class ChildType>
class Base : CrtpBase<ChildType>
{
public:
    void foo()
    {
        this->real_this().boo();
    }
};

class Derived1 : public Base<Derived1>
{
public:
    void boo { ... }
};

class Derived2 : public Base<Derived2>
{
public:
    void boo { ... }
};

The thing is, I want to use my classes in this way:

std::vector<Base*> base_vec;
base_vec.push_bach(new Derived1());
base_vec.push_bach(new Derived2());
.........
base_vec[0]->foo();

But this isn't possible, because base class for all derived classes is different (actually Base isn't a type at all, it's template). So, is there a way to use crtp with multiple derived classes, alongside with polymorphism?

Angew is no longer proud of SO

Indeed there is, you need to add the appropriate non-template base class too:

class AbstractBase
{
public:
  virtual ~AbstractBase() {}

  virtual void foo() = 0;
};


template <class ChildType>
class Base : CrtpBase<ChildType>, public AbstactBase
{
  void foo() override { this->real_this().boo(); }
};

Then, declare your vector as std::vector<AbstractBase*>.

This does indeed introduce the overhead of dynamic dispatch (which you were probably trying to avoid by using CRTP), but dynamic dispatch is the only way to get runtime polymorphism in C++.

It can still be beneficial, though. For example, if the implementation of foo is shared by all the derived classes, but calls into many different boo-style functions (with each derived class having a different implementation of those), you will only pay the dynamic dispatch cost once when invoking foo, and then all the calls made within foo are dispatched statically, CRTP-style.

On the other hand, if it's just one call to a boo-like function within foo, you may as well make boo virtual, put non-virtual foo into the base, thus getting rid of CRTP. The cost will be the same then: a non-virtual dispatch (foo) and a virtual one (boo).


Side note, you should strongly consider storing smart pointers in the std::vector; owning raw pointers are bad practice.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Can you use constraints on derived classes in CRTP methods?

From Dev

Can I use Spring @Autowired in multiple classes?

From Dev

How can I pass multiple parameters and use them?

From Dev

How can I use @for in sass to assign background positions to multiple classes

From Dev

How can I use @for in sass to assign background positions to multiple classes

From Java

How to use aggregated initialization in derived class with CRTP pattern?

From Dev

How to use an interface between classes and derived classes?

From Dev

Can I forward template arguments of a derived class to the base in CRTP?

From Dev

How can I call the constructor of the derived class when using CRTP?

From Dev

I can "pickle local objects" if I use a derived class?

From Dev

How can I use multiple 'Data' instance when one of them is 'deduced' from a type function?

From Dev

Can I get iterators from an ArrayList in multiple threads and use all of them safelly?

From Dev

How can I use multiple b-form-radio-group avoiding visual interference among them?

From Java

Can I use non existing CSS classes?

From Dev

Why can I not use operator overloading for classes?

From Dev

How can I use Unity with internal classes?

From Dev

Can I use select from derived tables with JPA?

From Dev

How can I combine templated derived class in CRTP with derived class expression templates?

From Dev

When to use templates rather than derived classes

From Dev

How to use arrays or vectors of pointers polymorphically?

From Dev

design an abstract class so that any one can extend it and use the extended class polymorphically

From Dev

Multiple storyboards: should I use a singleton pattern to cache them?

From Dev

Multiple storyboards: should I use a singleton pattern to cache them?

From Java

Why can I type alias functions and use them without casting?

From Dev

How can I find files and then use xargs to move them?

From Dev

Can I use Eclipse templates to insert methods and also call them?

From Dev

Can I use one definition of two Button by switching between them?

From Dev

What are Launchpad packaging recipes and how can I use them?

From Dev

Are addListener and addEventListener the same? Can I use them interchangeably?

Related Related

  1. 1

    Can you use constraints on derived classes in CRTP methods?

  2. 2

    Can I use Spring @Autowired in multiple classes?

  3. 3

    How can I pass multiple parameters and use them?

  4. 4

    How can I use @for in sass to assign background positions to multiple classes

  5. 5

    How can I use @for in sass to assign background positions to multiple classes

  6. 6

    How to use aggregated initialization in derived class with CRTP pattern?

  7. 7

    How to use an interface between classes and derived classes?

  8. 8

    Can I forward template arguments of a derived class to the base in CRTP?

  9. 9

    How can I call the constructor of the derived class when using CRTP?

  10. 10

    I can "pickle local objects" if I use a derived class?

  11. 11

    How can I use multiple 'Data' instance when one of them is 'deduced' from a type function?

  12. 12

    Can I get iterators from an ArrayList in multiple threads and use all of them safelly?

  13. 13

    How can I use multiple b-form-radio-group avoiding visual interference among them?

  14. 14

    Can I use non existing CSS classes?

  15. 15

    Why can I not use operator overloading for classes?

  16. 16

    How can I use Unity with internal classes?

  17. 17

    Can I use select from derived tables with JPA?

  18. 18

    How can I combine templated derived class in CRTP with derived class expression templates?

  19. 19

    When to use templates rather than derived classes

  20. 20

    How to use arrays or vectors of pointers polymorphically?

  21. 21

    design an abstract class so that any one can extend it and use the extended class polymorphically

  22. 22

    Multiple storyboards: should I use a singleton pattern to cache them?

  23. 23

    Multiple storyboards: should I use a singleton pattern to cache them?

  24. 24

    Why can I type alias functions and use them without casting?

  25. 25

    How can I find files and then use xargs to move them?

  26. 26

    Can I use Eclipse templates to insert methods and also call them?

  27. 27

    Can I use one definition of two Button by switching between them?

  28. 28

    What are Launchpad packaging recipes and how can I use them?

  29. 29

    Are addListener and addEventListener the same? Can I use them interchangeably?

HotTag

Archive