Нужно ли нам отдельно определять статические члены, даже если они инициализируются внутри определения класса?

В C++03 у нас была возможность инициализировать conststatic члены данных класса встроены в определение класса, но все же должны были определить член, если он должен был использоваться odr.

Это все еще так в C++11?

struct Foo
{
   static const int x = 3;
};

const int Foo::x;
// ^ required?

1 ответ

Решение

Да.

[C++11: 9.4.2/3]: Если энергонезависимый conststatic элемент данных имеет целочисленный тип или тип перечисления, его объявление в определении класса может указывать инициализатор скобок или равных, в котором каждое предложение инициализатора, являющееся выражением присваивания, является константным выражением (5.19). static член данных литерального типа может быть объявлен в определении класса с помощью constexpr спецификатор; если это так, его объявление должно указывать инициализатор скобок или равных, в котором каждое предложение инициализатора, являющееся выражением присваивания, является константным выражением. [Примечание: в обоих этих случаях член может появляться в константных выражениях. - примечание конца] Элемент все еще должен быть определен в области пространства имен, если он используется в программе с помощью odr (3.2), и определение области пространства имен не должно содержать инициализатор.

Это сопоставимо с формулировкой в ​​C++03:

[C++03: 9.4.2/2]: Если статический член данных имеет const интеграл или const Тип перечисления, его объявление в определении класса может указывать инициализатор константы, который должен быть выражением целочисленной константы (5.19). В этом случае член может появляться в виде целочисленных константных выражений. Член по-прежнему должен быть определен в области пространства имен, если он используется в программе и определение области пространства имен не должно содержать инициализатор.

Как видите, само правило вообще не изменилось, за исключением введения правил для constexpr,

Другие вопросы по тегам