Нужно ли нам отдельно определять статические члены, даже если они инициализируются внутри определения класса?
В C++03 у нас была возможность инициализировать const
static
члены данных класса встроены в определение класса, но все же должны были определить член, если он должен был использоваться odr.
Это все еще так в C++11?
struct Foo
{
static const int x = 3;
};
const int Foo::x;
// ^ required?
1 ответ
Да.
[C++11: 9.4.2/3]:
Если энергонезависимыйconst
static
элемент данных имеет целочисленный тип или тип перечисления, его объявление в определении класса может указывать инициализатор скобок или равных, в котором каждое предложение инициализатора, являющееся выражением присваивания, является константным выражением (5.19).static
член данных литерального типа может быть объявлен в определении класса с помощьюconstexpr
спецификатор; если это так, его объявление должно указывать инициализатор скобок или равных, в котором каждое предложение инициализатора, являющееся выражением присваивания, является константным выражением. [Примечание: в обоих этих случаях член может появляться в константных выражениях. - примечание конца] Элемент все еще должен быть определен в области пространства имен, если он используется в программе с помощью odr (3.2), и определение области пространства имен не должно содержать инициализатор.
Это сопоставимо с формулировкой в C++03:
[C++03: 9.4.2/2]:
Если статический член данных имеетconst
интеграл илиconst
Тип перечисления, его объявление в определении класса может указывать инициализатор константы, который должен быть выражением целочисленной константы (5.19). В этом случае член может появляться в виде целочисленных константных выражений. Член по-прежнему должен быть определен в области пространства имен, если он используется в программе и определение области пространства имен не должно содержать инициализатор.
Как видите, само правило вообще не изменилось, за исключением введения правил для constexpr
,