如何在命名空间范围内转发声明constexpr对象?

Eri*_*ler 8 c++ gcc clang c++11

在clang(trunk)上我可以转发声明一个稍后定义的对象,constexpr如下所示:

// Fwd-declarations
struct S;
extern const S s;

// (... later) definitions
struct S {};
constexpr S s {};
Run Code Online (Sandbox Code Playgroud)

Gcc 4.8不喜欢这样,告诉我前向声明和定义在constexpr-ness中有所不同.是gcc说实话,还是这只是一个gcc bug?

Ada*_*son 5

我在C++ 11标准的副本中找不到明确禁止constexpr声明和定义之间错误匹配的语言的任何语言,但我确实看到语言明确禁止constexpr使用extern(第7.1.5节) ,我也看到语言要求类级static constexpr变量的初始化器在类中.此外,由于constexpr当变量或其类型的定义不可用时,实用性显着降低,我认为可能的意图是在声明constexpr变量时必须定义变量(或者,对于static类成员,初始化).

作为解决方法,也许您可​​以为extern变量提供别名.这将允许您获取其地址,这是我能够想到的前瞻性声明允许的唯一内容.例如:

// .hpp file:
struct C;
extern C const &c;

// .cpp file:
struct C {
    constexpr C() { }
};
constexpr C cc;
C const &c = cc;
Run Code Online (Sandbox Code Playgroud)

旁注:我知道在C++ 14中,他们重新访问/正在重新访问constexpr,因此它可能在Clang中起作用,因为它正在实现C++ 14的一些草案规范.


Eri*_*ler 4

真正的答案是 gcc 是完全错误的,clang 是正确的。上面的代码应该可以编译,并且在 gcc 4.9 中可以编译。或者这个错误报告是这么说的。