Skip to main content
GameDev.net gamedev.net
🔒 Locked

Using a vector of base classes with CRTP

Started by johnmarinelli Mar 3, 2014 at 4:57 AM 1 replies 6.9k views
Original Post
johnmarinelli
johnmarinelli

Hey guys,

So I am messing around with the Curiously Recurring Template Pattern, and was wondering:

is there a way to access a 'base class' that uses CRTP to call functions?

for example:


template<typename C>
class Entity 
{
private:
        //helper function for polymorphic functions
        C* getChild()
        {
                return static_cast<C*>(this);
        }

public:
        Entity() {}

        void paint()
        {
                getChild()->display();
        }
}


//...

//another question: can vectors hold templated types?
template<typename T>
std::vector< Entity<T>* > entities;

int main()
{
  for(auto i : entities){
      i->paint();
  }
}

i'm trying something similar and it's not working.

this is the only stackoverflow question i could find that is related:

http://stackoverflow.com/questions/16527673/c-one-stdvector-containing-template-class-of-multiple-types

Note: I'm not actually deving, but am playing around with the CRTP to learn it. Otherwise I'd strongly adhere to KISS

Hodgman
Hodgman
template<typename T>
std::vector<T> collection;
^^^ You can't have a templated variable like that.
That's saying, that when someone tries to use 'collection', instantiate a version of it for each T that they use... You use templates like that on functions/classes, but not variables.
e.g.
template<typename T>
std::vector<T>& foo()
{
  static std::vector<T> collection;
  return collection;
}
std::vector<int>& foo_int = foo<int>();
Your code should work if you remove the invalid template, but you can only put entities of one type in each vector:
class Foo : public Entity<Foo>{};
std::vector< Entity<Foo>* > entities;
int main()
{
  for(auto i : entities){
      i->paint();
  }
}
If you want to put different types in a list, you're after run-time polymorpism, not compile-time polymorphism afforded by CRTP:
class IEntity {
public: virtual void paint();
};
template<typename C>
class Entity : public IEntity
{...
l0calh05t
l0calh05t

template<typename T>
std::vector<T> collection;
^^^ You can't have a templated variable like that.
That's saying, that when someone tries to use 'collection', instantiate a version of it for each T that they use... You use templates like that on functions/classes, but not variables.
e.g.

C++14 will add template variables (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3651.pdf)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.