是的,它的格式不正确。原因如下:
函数在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
函数,需要在编译期间调用之前在翻译单元中使用它们之前定义,否则编译器将不得不进行多次传递,只是为了“链接”常量表达式以进行评估。