我使用的是 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 () {}
这是错误:
error: size of array ‘array’ is not an integral constant-expression
是否禁止以这种方式使用 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
函数需要在编译期间被调用之前在翻译单元中使用之前定义,否则编译器将不得不进行多次传递以“链接”常量表达式评估。
关于c++ - 如果函数在类范围内声明,则 constexpr 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16493652/