我正在使用g++ 4.8.0,其中不包含早期的constexpr
错误。因此下面的代码可以工作fine:
constexpr int size() { return 5; }
int array[size()];
int main () {}
但是,如果我将两个变量都包含在
class
中作为static
,则它给出compiler error:struct X {
constexpr static int size() { return 5; }
static const int array[size()];
};
int main () {}
这是错误:
是否禁止以这种方式使用
constexpr
或另一个g++错误? 最佳答案
是的,它格式不正确。原因如下:
在常量表达式中使用constexpr
函数之前,需要先对其进行定义(而不是声明)。
因此,例如:
constexpr int f(); // declare f
constexpr int x = f(); // use f - ILLEGAL, f not defined
constexpr int f() { return 5; } // define f, too late
类说明符内的函数定义(以及初始化程序和默认参数)实际上是按照在类外部定义的顺序进行解析的。
所以这:
struct X {
constexpr static int size() { return 5; }
static const int array[size()];
};
按以下顺序解析:
struct X {
constexpr inline static int size(); // function body defered
static const int array[size()]; // <--- POINT A
};
constexpr inline int X::size() { return 5; }
即,将函数体的解析推迟到类说明符之后。
推迟进行函数体解析的目的是,使函数体可以转发当时尚未声明的引用类成员,并且还可以将自己的类用作完整类型:
struct X
{
void f() { T t; /* OK */ }
typedef int T;
};
与命名空间范围相比:
void f() { T t; /* error, T not declared */ }
typedef int T;
在
POINT A
处,编译器尚没有size()
的定义,因此无法调用它。为了获得编译时性能,需要在转换单元中使用constexpr
函数之前先定义ojit_code函数,然后在编译过程中对其进行调用,否则编译器将不得不进行多次遍历,才能“链接”常量表达式以进行评估。