11

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

4

2 回答 2

9

在 C++14 标准中,很明显需要初始化。从第 7.5.1 节第 9 段,

对象声明中使用的constexpr说明符将对象声明为 const。这样的对象应具有文字类型并应被初始化。

至于“对象声明”的确切含义,第 7 节第 7 段规定:

如果 decl-specifier-seq 不包含 typedef 说明符,则如果与名称关联的类型是函数类型,则该声明称为函数声明,否则称为对象声明。

于 2015-10-18T12:56:44.630 回答
9

叮当是正确的。变量模板的声明是一个对象声明 ([dcl.dcl]/9),因此它必须按照 [dcl.constexpr]/9 提供一个初始化器:

对象声明中使用的constexpr说明符将对象声明为const. 这样的对象 […] 应被初始化。

但是,实际上没有办法像一开始那样“向前”声明一个对象constexpr。如果constexpr应用于变量的声明,它应该是一个定义([dcl.constexpr]/1)。

于 2015-10-18T12:58:53.840 回答