Инициализация статического константного члена в шаблонном классе - PullRequest
7 голосов
/ 22 июля 2010

У меня проблема с инициализацией элемента static const. В шаблонном классе я определяю константный член и инициализирую его вне класса.
Когда я включаю файл .h, где этот класс реализован в нескольких файлах .cpp, я получаю ошибку LNK2005 (я использую VS2010), которая говорит, что константа уже определена .

// List.hpp
template <class T>
class List {
    static const double TRIM_THRESHOLD;
};

template <class T>
const double List<T>::TRIM_THRESHOLD = 0.8;

Я попытался поместить инициализацию члена в файл .cpp, но затем я получил ошибку компоновщика, говорящую, что константа вообще не определена. Если список не шаблонизирован и я помещаю инициализацию в файл .cpp, все в порядке.
Есть ли решение для этой ситуации? У меня уже есть # ifdef / define предложения вокруг файла, и это определенно не решение.

1 Ответ

7 голосов
/ 22 июля 2010

Вы должны определить константу в исходном файле, а не заголовок (поэтому он определяется только один раз), так как это шаблон, который нужно сохранить в заголовке (и все экземпляры имеют одинаковое значение), вы можете использовать общийбазовый класс.

class ListBase {
protected:
    ListBase() {} // use only as base 
    ~ListBase() { } // prevent deletion from outside
    static const double TRIM_THRESHOLD;    
};

template <class T>
class List : ListBase {  
};

// in source file
double ListBase::TRIM_THRESHOLD = 0.8;

Другой вариант - использовать его в качестве статической функции:

    static double trim_threashold() { return 0.8; }

Редактировать: Если ваш компилятор поддерживает C ++11 вы делаете свой метод static функцией constexpr , чтобы он имел все возможности оптимизации, которые имеет непосредственное использование значения.

...