Ken P
Ken P

Reputation: 576

C++: Trying to create a const static member in template

Here is the code I am trying to get to compile:

foo.h:

#include <limits>

template <typename T> class STreeNode {
public:
    T key;
    STreeNode<T>* child[2];
    STreeNode( const T& k ) :
        key(k), child{ nullptr, nullptr } {}; 
};

template <typename T>
class STree {
    STreeNode<T> *root;
    static constexpr T sentinel1 = std::numeric_limits<T>::min();
    static constexpr T sentinel2 = std::numeric_limits<T>::max();
public:
    STree() {
        root = new STreeNode<T>( sentinel1 );
    }
};

And I then instantiate it with:

#include <limits>
#include "foo.h"

int main() {
    STree<long long> t;
}

This compiles fine, but when it attempts to link, I get an undefined reference to STree<long long int>::sentinel1. How can I resolve this?

Upvotes: 0

Views: 101

Answers (1)

tryptik
tryptik

Reputation: 36

Static members have to be initialized in a translation unit. When you instantiate the template, the compiler generates the code where it is declared. I haven't had a chance to use constexpr yet, but I'm betting you can't assign to a static member in the template class definition as you have to include the static initialization outside the class. I'm betting the following will work:

template <typename T>
class STree {
    STreeNode<T> *root;
    static const T sentinel1;
    static const T sentinel2;
public:
    STree() {
        root = new STreeNode<T>( sentinel1 );
    }
};

template<typename T>
const T STree<T>::sentinel1 = std::numeric_limits<T>::min();

template<typename T>
const T STree<T>::sentinel2 = std::numeric_limits<T>::max();

Upvotes: 2

Related Questions