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


148

Я хотів би зробити це:

template <typename T>
struct S
{
    ...
    static double something_relevant = 1.5;
};

але я не можу, оскільки something_relevantне є цілісним типом. Це не залежить від того T, але існуючий код залежить від того, чи є статичним членом S.

Оскільки S є шаблоном, я не можу помістити визначення всередині компільованого файлу. Як вирішити цю проблему?


також стосується std::stringтипу
Тревор Бойд Сміт

Оскільки c ++ 11 ключове слово inline змінилося, так що статичні змінні можна ініціалізувати в точці оголошення. Тож декларація для цього виглядатиме як "вбудований статичний подвійний something_relevant = 1,5;"

@ user8991265 Я вважаю, що вбудовані змінні доступні, оскільки C ++ 17, а не C ++ 11.
zupazt3

Відповіді:


195

Просто визначте це у заголовку:

template <typename T>
struct S
{
    static double something_relevant;
};

template <typename T>
double S<T>::something_relevant = 1.5;

Оскільки він є частиною шаблону, як і у всіх шаблонах, компілятор переконається, що він визначений лише один раз.


4
@sbi: чи не порушує це одне правило визначення?
Олександр Ч.

7
Ні, ні, якщо ми говоримо про шаблони. Інакше шаблони функцій теж зробили б це.
sbi

1
@sbi, @Prasoon: насправді Prasoon здається першим. Але я все ще приймаю sbi через коментар щодо ODR (який був моїм основним питанням).
Олександр К.

1
@sbi просто наведіть курсор на текст :)
Йоганнес Шауб - ліб

5
@Johannes: Чорт, я тут рік, і я цього не знав! Що ще мені не вистачає? (Я все ще пам’ятаю ганьбу, коли виявив, що два числа, що з’являються, коли я клацаю на кількість голосів, - це не помилка, а особливість.) <goes_playing>Нічого, коли я наведіть курсор на ваше ім’я, я бачу вашу представницю! Я теж цього не знав. @Prasoon: Ні, ти маєш рацію, я ітеративно прибув туди, де зараз. (Ось чому я голосував вашу відповідь, BTW.)
sbi

37

Оскільки C ++ 17, тепер ви можете оголосити статичний член як inline, який визначатиме змінну у визначенні класу:

template <typename T>
struct S
{
    ...
    static inline double something_relevant = 1.5;
};

наживо: https://godbolt.org/g/bgSw1u


1
Це відмінна відповідь. Короткий і точний. Дивіться також en.cppreference.com/w/cpp/language/static#Static_data_members для отримання додаткової інформації.
andreee

31

Це спрацює

template <typename T>
 struct S
 {

     static double something_relevant;
 };

 template<typename T>
 double S<T>::something_relevant=1.5;

Я не визначив змінну something_relevant (я видалив template<typename T> double S<T>::something_relevant=1.5;)компілятор, який кидає помилку. Можете, скажіть, будь ласка, в чому причина?
goodman
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.