Без inline
это явно указано только как объявление. Как указано в [class.static.data]/2
Объявление невстроенного статического члена данных в его определении класса не является определением и может иметь неполный тип, отличный от cv void. Определение статического члена данных, который не определен как встроенный в определение класса, должно появиться в области пространства имен, охватывающей определение класса члена.
Обоснование, скорее всего, состоит в том, чтобы сохранить устаревший код неповрежденным и действительным. Вспомните, что мы могли инициализировать целочисленные константы в самом определении класса почти всегда. Но odr-использование их по-прежнему требовало внеклассового определения в какой-то единице перевода.
Таким образом, сделать такие переменные неявно встроенными может быть проблематично в существующих кодовых базах. Комитет всегда думает об обратной совместимости при добавлении основных функций языка.
Например, рассмотрим это допустимое определение класса C++03:
struct foo {
static const int n = 3;
double bar[n];
};
n
можно использовать как константное выражение для определения степени bar
, и это не считается использованием odr. В настоящее время мы бы написали это как constexpr
1, однако указанное выше по-прежнему актуально. Но могут быть случаи, когда n
придется использовать odr (представьте, что его адрес взят, или ссылка привязана к нему и т. д.). Их, вероятно, не так много и, вероятно, они не распространены, но у некоторых API есть сумасшедшие требования, которые в конечном итоге потребуют этого.
const int foo::n;
появляться в какой-либо единице перевода.
Теперь, если бы static inline int i = 8;
вдруг неявно стало inline
, приведенное выше определение (то есть в существующей кодовой базе) было бы нарушением ODR. Теперь ранее хорошо сформированный код плохо сформирован. Поэтому лучше всего разрешить здесь действовать только явным inline
, так как на самом деле они будут только в новом коде.
1 Можно возразить, что static constexpr
переменные могут иметь одинаковую проблему (и тем не менее они неявно встроены). Но их первоначальная формулировка IIRC позволила это изменение без потенциального нарушения существующего кода. По сути, он уже был «встроенным» во всем, кроме имени.
person
StoryTeller - Unslander Monica
schedule
22.10.2017