2015-10-18 5 views
9

я пытался передать, объявить constexpr переменную шаблон:вперед объявить constexpr переменную шаблона

template<typename> 
constexpr std::size_t iterator_category_value; 

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

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 с переадресацией, которая не является шаблоном переменной, поэтому контекст шаблона переменных, по-видимому, является тем, что делает компиляторы несогласными.

+0

Текст http://wg21.cmeerw.net/cwg/issue1712 подразумевает, что вы не можете переадресовать его как 'constexpr', однако я не совсем уверен, как std запрещает его. Шаблон переменной не выглядит как объявление объекта * для меня. – dyp

+0

OTOH, [dcl.dcl] p9 кажется очень общим и должен применяться к переменным шаблонам (=> шаблоны переменных - объявления объектов => 'constexpr' требует инициализации) – dyp

+0

@dyp Кстати, что вы подразумеваете под« сейчас »? Разве вы не компилируете самые современные источники, доступные в настоящее время в Git? – Columbo

ответ

8

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

A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized.

Что касается точного значения "объект декларации", раздел 7 пункта 7 гласит:

If the decl-specifier-seq contains no typedef specifier, the declaration is called a function declaration if the type associated with the name is a function type and an object declaration otherwise.

8

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

A constexpr specifier used in an object declaration declares the object as const . Such an object […] shall be initialized.

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

+0

[Что-то изменилось в последнее время?] (Http: // coliru. stacked-crooked.com/a/cb1d8ebe90a2bc11) – Orient

+0

Просто код, содержащий обсуждаемый случай. Он содержит форвардное объявление шаблона переменной 'constexpr', но компилируется в порядке. – Orient

+0

@Orient Вы понимаете, что компилируете компилятор, который прослушивается в этом отношении? – Columbo

Смежные вопросы