我尝试向前声明一个constexpr
变量模板,如下所示:
template<typename>
constexpr std::size_t iterator_category_value;
目标是记录每个专业都应该是constexpr
,但我必须承认,我从未检查过它是否合法,并且g ++对它很满意。但是,当我尝试使用clang ++编译此spinnet时,我收到以下错误:
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 :(得分:8)
在C ++ 14标准中,似乎很清楚需要初始化。从第7.5.1节第9段开始,
对象声明中使用的
constexpr
说明符 将对象声明为const。这样的对象应该有 文字类型,应初始化。
至于“对象声明”的确切含义,第7节第7段规定:
如果decl-specifier-seq不包含typedef说明符, 如果声明被称为函数声明 与名称关联的类型是函数类型和 否则就是一个对象声明。
答案 1 :(得分:8)
Clang是对的。变量模板的声明是一个对象声明([dcl.dcl] / 9),因此必须根据[dcl.constexpr] / 9提供初始化器:
对象声明中使用的
constexpr
说明符声明了 对象为const
。 这样的对象应该是 初始化。强>
实际上没有任何方式可以转发&#34;但是,首先将对象声明为constexpr
;如果constexpr
应用于变量的声明,则它应该是一个定义([dcl.constexpr] / 1)。