0

I'm implementing some ideas using templates and static members. Although the "real" code produces another error, this is the one which i still have on a toy example code

#include <string>
#include <iostream>

template<int dim>
class Class1 {
  public:
     Class1() {};
    ~Class1() {};
     void foo() {
        std::cout<<"foo-1"<<std::endl;
     }
   protected:
     std::string name;
};

template<int dim>
class Class2 : public Class1<dim>
{
  public:
     Class2(const int & a, const int &b) : 
        number( Class2<dim>::id_generator++ ) 
     {
        Class1<dim>::name = "My-name"; 
        foo(); // (1)
      };

 void foo() {
    Class1<dim>::foo();
    std::cout<<"foo-2"<<std::endl;
 }

 private:
    const unsigned int number;
    static unsigned int id_generator;
};

 int main() 
 {
    int a = 1, b=2;
    Class2<2> class2(a,b);   // (2)
 }

with the linker error:

 undefined reference to `Class2<2>::id_generator' 

rea-life example produces 2 errors

 (1) required from 'Class2<dim>::Class2(int, int) [with int dim = 3]'
 (2) required from here.

that real-life errors tell me absolutely nothing at all! :( I hope if the toy-problem is solved, the real-life one will be gone too, but if anyone has any ideas on the "real-life" errors (those 2 lines) in the context of the structure, pls, let me know.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Denis
  • 1,526
  • 6
  • 24
  • 40

2 Answers2

1

You forgot to add a definition for your static data member id_generator. Add this at global namespace level:

template<int dim>
unsigned int Class2<dim>::id_generator = 0;

With this addition, you can see your code correctly compiling and linking here.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
1

Well, as the error message says, there is no definition of the static data member. If this was an ordinary class, you'd put the definition in a source file:

// header:
class C {
    static int i;
};

// source:
int C::i = 3;

A template is a pattern; the compiler uses it to generate code. So what you want to end up with when the compiler instantiates the template is something like the preceding code. But template code goes in headers, not source files, so you write it like this:

// header:
template <class T>
class C {
    static int i;
};

template <class T>
int C<T>::i = 3;
Pete Becker
  • 74,985
  • 8
  • 76
  • 165