0

I am trying understand the concept of static data member templates. And i came across the following example in a book:

class Collection {
    public: 
    
    template<typename T>
    static T zero = 0;
}; 

When i try to execute the program it gives the error that:

undefined reference to `Collection::zero<int>'

To solve the above error i tried added the following code in the above program but it still gives error:

template<typename T> T Collection::zero = 0; //even after adding this it still gives error

Error now says:

duplicate initialization of 'Collection::zero'

My question is that is this a mistake(typo) in this example of the book. If yes, then what is the problem and how can i solve it?

Jason
  • 36,170
  • 5
  • 26
  • 60
  • Yes this is definitely a typo in the book. – Jason Jan 25 '22 at 11:07
  • Ok can you tell me more about why it happens and how to solve it. – Jason Jan 25 '22 at 11:12
  • Initialize inline in the class, or initialize in the definition. Don't initialize in both places. – Some programmer dude Jan 25 '22 at 11:12
  • Or make it `const` (seems a good fit here), then it can be initialized in-class as long as it's taken by value, but not reference/pointer. Or even better, if it's a compile time constant, `constexpr`, it also implies `inline` then. – alagner Jan 25 '22 at 11:43

2 Answers2

3

Yes this is a typo in the book. The problem is that you've specified an initializer for the static data member template even though it is not inline.

Solution

There are 2 ways to solve this problem both of which are given below.

Method 1: C++17

In C++17, you can make use of the keyword inline.

class Collection {
    public:
    
    
    template<typename T>
    inline static T zero = 0; //note the keyword inline here
}; 
//no need for out of class definition of static data member template
int main(){
    int x =Collection::zero<int>;
}

Method 2: C++14

In this case you need to remove the initializer 0 from the in-class declaration of the static data member template.

class Collection {
    public:
    
    template<typename T>
    static T zero ; //note initializer 0 removed from here since this is a declaration
}; 

template<typename T> T Collection::zero = 0;
int main(){
    int x =Collection::zero<int>;
}
Jason
  • 36,170
  • 5
  • 26
  • 60
-1

It is not an issue template-specific but initialization of static members for class. The difference is that in case of templates you usually have full implementation in header so you have no cpp file (and no compilation unit) related to this class. You can add this definition/initialization e.g. in cpp with your class or just in file where you use this template, depends on structure of your project.

Karol T.
  • 543
  • 2
  • 13
  • I have given a link in my question to the program that shows the error that i am getting. This error is not related to header or source file issues. – Jason Jan 25 '22 at 11:22
  • I've mentioned about headers since it is the common case. No matter how you organize code but the easier way is to define static members outside the class itself. However you have example of solution above (c++14 version) so it doesn't matter. – Karol T. Jan 25 '22 at 11:35