【发布时间】:2012-07-16 08:50:43
【问题描述】:
要求
我想要一个从 constexpr 函数计算的 constexpr 值(即编译时常量)。我希望这两个范围都在一个类的命名空间内,即一个静态方法和一个类的静态成员。
第一次尝试
我首先以(对我而言)显而易见的方式写了这个:
class C1 {
constexpr static int foo(int x) { return x + 1; }
constexpr static int bar = foo(sizeof(int));
};
g++-4.5.3 -std=gnu++0x 对此表示:
error: ‘static int C1::foo(int)’ cannot appear in a constant-expression
error: a function call cannot appear in a constant-expression
g++-4.6.3 -std=gnu++0x 抱怨:
error: field initializer is not constant
第二次尝试
好吧,我想,也许我必须把东西移出课堂。所以我尝试了以下方法:
class C2 {
constexpr static int foo(int x) { return x + 1; }
constexpr static int bar;
};
constexpr int C2::bar = C2::foo(sizeof(int));
g++-4.5.3 将毫无怨言地编译它。不幸的是,我的其他代码使用了一些基于范围的for 循环,所以我必须至少有 4.6。现在我仔细查看support list,似乎constexpr 也需要4.6。和g++-4.6.3 我得到了
3:24: error: constexpr static data member ‘bar’ must have an initializer
5:19: error: redeclaration ‘C2::bar’ differs in ‘constexpr’
3:24: error: from previous declaration ‘C2::bar’
5:19: error: ‘C2::bar’ declared ‘constexpr’ outside its class
5:19: error: declaration of ‘const int C2::bar’ outside of class is not definition [-fpermissive]
这对我来说听起来很奇怪。这里的“constexpr”有何不同?我不想添加-fpermissive,因为我更喜欢严格检查我的其他代码。将 foo 实现移到类主体之外没有明显的效果。
预期答案
有人可以解释这里发生了什么吗?我怎样才能实现我正在尝试做的事情?我主要对以下类型的答案感兴趣:
- 在 gcc-4.6 中实现此功能的一种方法
- 观察到后来的 gcc 版本可以正确处理其中一个版本
- 一个指向规范的指针,根据该规范,我的至少一个构造应该工作,这样我就可以让 gcc 开发人员真正让它工作起来
- 根据规范,我想要的信息是不可能的,最好有一些关于此限制背后的基本原理的洞察
也欢迎其他有用的答案,但可能不会那么容易被接受。
【问题讨论】:
-
在类定义之外移动
foo似乎可以解决 gcc 6.1 中的问题:请参见此处:link
标签: c++ gcc g++ static-members constexpr