Статическая членская инициализация константы в шаблонном классе

У меня есть проблема относительно 'статической константы' членская инициализация. В шаблонном классе я определяю участника константы и инициализирую его вне класса.
Когда я включаю.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 пункты вокруг файла, и это - определенно не решение.

7
задан Gratian Lup 22 July 2010 в 08:31
поделиться

1 ответ

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

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; }

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

8
ответ дан 7 December 2019 в 05:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: