0

I am going to get right to the point:

//ComponentHolder.h

template<class Holder, uint ID>
class TemplateComponentHolder : public ComponentHolderInterface {
protected:
    std::vector<ComponentType*> mComponents;


public:
   TemplateComponentHolder() : ComponentHolderInterface(ID) {}

   static const uint getStaticID() { return ID; }
};

class ConcereteComponentHolder1 : public TemplateClassHolder<ComponentType, 1000> {
public:
    inline void print() { std::cout << "test"; }
};

//World.h
class World {
private:
   std::map<uint, ComponentHolderInterface*> mHolders;
public:
   template<class Holder> Holder * getHolder() {
       auto i = mHolders.find(Holder::getStaticID());
       if(i != mHolders.end())
          return static_cast<Holder*>((*i));
       return NULL;
   }

   /* ... */
};

//Main code
int main() {
  World * world = new World;
  world->addHolder(new ConcerteComponentHolder1);

  world->getHolder<ConcreteComponentHolder1>()->print();
}

I get unresolved external symbol error. Says cannot resolve "ConcereteComponentHolder1::ID". If I change the static variable to non const and add it to a source file:

//ComponentHolder.cpp
uint ConcreteComponentHolder1::ID = 1000;

There is no problem. It makes sense why the latter one must be defined explicitly. But when I am using const, I have to define it in the header. Getting a linker error when using const just doesn't make sense. Is it because of the template function being generated in the header? Or is it something else?

Gasim
  • 7,615
  • 14
  • 64
  • 131
  • "When I am using `const`, I have to define it in the header". Why? – TemplateRex Jan 09 '14 at 10:26
  • I just realized that I can use const in the definition. I just wish there was an easier way to approach this problem. Like using a static `getId()`, then I won't need to define it every time. – Gasim Jan 09 '14 at 10:38
  • If you're really using C++11 it is possible: `constexpr uint getId() { return 1; }` – Nicola Musatti Jan 09 '14 at 10:57
  • 1
    Not only did getting right to the point not really get right to the point, after you edited your code the question made little sense. – Michael Burr Jan 09 '14 at 11:07

1 Answers1

1

Placing a variable declaration together with an initialiser in the class declaration dies not actually constitute a definition. You can get away without the definition as long as you only ever take it's value and never try to use it as a reference.

'find' takes a reference to the value as an argument. This means you need an actual variable defined somewhere to take a reference to it.

You might also like to read this SO question: Defining static const integer members in class definition

Community
  • 1
  • 1
harmic
  • 28,606
  • 5
  • 67
  • 91
  • one question. Instead of using ID as a variable I have created a getStaticID() static function and each subclass defines it all. Please check my edited new code. the getStaticId works as expected but I want to know if its just my compiler linking it correctly or is it a valid code? Can derived class access the static function of a parent class? – Gasim Jan 09 '14 at 11:00
  • Because you are using a template function which in which the specific class is parameterized, you are accessing the static method of the derived class, not the parent. Or did I misunderstand your question? – harmic Jan 09 '14 at 11:14
  • Btw probably best not to edit the question like that. The question and the answer now do not make sense to anyone else searching for this kind of problem. – harmic Jan 09 '14 at 11:15