转发声明constexpr变量模板

时间:2015-10-18 12:15:45

标签: c++ language-lawyer c++14 constexpr variable-templates

我尝试向前声明一个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变量不是变量模板,因此变量模板上下文似乎是编译器不同意的原因。

2 个答案:

答案 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)。