Я пытался переслать-объявить 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
переменная, которая не является переменным шаблоном, поэтому контекстный шаблон переменной, по-видимому, является причиной несогласия компиляторов.
В стандарте C ++ 14 кажется довольно ясным, что требуется инициализация. Из раздела 7.5.1, пункт 9,
constexpr
спецификатор, используемый в объявлении объекта
объявляет объект как const. Такой объект должен иметь
литеральный тип и должен быть инициализирован.
Что касается точного значения «объявления объекта», в разделе 7 параграфа 7 говорится:
Если decl-specier-seq не содержит спецификатора typedef,
объявление называется объявлением функции, если
тип, связанный с именем, является типом функции и
в противном случае объявление объекта.
Clang это правильно. декларация шаблона переменной является объявлением объекта ([dcl.dcl] / 9), следовательно, он должен предоставлять инициализатор согласно [dcl.constexpr] / 9:
constexpr
спецификатор, используемый в объявлении объекта, объявляет
объект какconst
, Такой объект […] должен быть
инициализируется.
По сути, нет способа «вперед» объявить объект как constexpr
во-первых, хотя; Если constexpr
применяется к объявлению переменной, это должно быть определение ([dcl.constexpr] / 1).