Форвард объявить шаблон переменной constexpr

Я пытался переслать-объявить constexpr переменный шаблон как этот:

template<typename>
constexpr std::size_t iterator_category_value;

Цель состояла в том, чтобы документально подтвердить, что каждая специализация должна быть constexpr но я должен признать, что я никогда не проверял, было ли это законно или нет, и G ++ был доволен этим. Однако, когда я попытался скомпилировать этот спиннет с помощью clang ++, я получил следующую ошибку:

error: default initialization of an object of const type 'const std::size_t' (aka 'const unsigned long')
constexpr std::size_t iterator_category_value;
^
= 0

Ошибка имеет смысл, и удаление constexpr заставляет его исчезнуть, так что это не настоящая проблема. Тем не менее, мне любопытно: стандарт позволяет constexpr предварительное объявление для шаблона переменной или это незаконно? g ++ и clang ++, кажется, не согласны, и я хотел бы знать, где я должен представить отчет об ошибке, если это необходимо.

Они оба жалуются на заранее объявленную constepxr переменная, которая не является переменным шаблоном, поэтому контекстный шаблон переменной, по-видимому, является причиной несогласия компиляторов.

9

Решение

В стандарте C ++ 14 кажется довольно ясным, что требуется инициализация. Из раздела 7.5.1, пункт 9,

constexpr спецификатор, используемый в объявлении объекта
объявляет объект как const. Такой объект должен иметь
литеральный тип и должен быть инициализирован.

Что касается точного значения «объявления объекта», в разделе 7 параграфа 7 говорится:

Если decl-specier-seq не содержит спецификатора typedef,
объявление называется объявлением функции, если
тип, связанный с именем, является типом функции и
в противном случае объявление объекта.

8

Другие решения

Clang это правильно. декларация шаблона переменной является объявлением объекта ([dcl.dcl] / 9), следовательно, он должен предоставлять инициализатор согласно [dcl.constexpr] / 9:

constexpr спецификатор, используемый в объявлении объекта, объявляет
объект как const, Такой объект […] должен быть
инициализируется.

По сути, нет способа «вперед» объявить объект как constexpr во-первых, хотя; Если constexpr применяется к объявлению переменной, это должно быть определение ([dcl.constexpr] / 1).

8

По вопросам рекламы [email protected]