考虑一个具有常量成员的类:
class foo {
public:
const static int N;
};
foo::N
需要初始化:
constexpr int foo::N = 5;
并注意在这里如何使用constexpr
限定词而不是const
似乎是一个错误。
但是GCC,Clang和MSVC都可以编译!
Clang甚至同时允许两个限定符版本:
constexpr int foo::N = 3;
const int foo::N = 5;
int main(){
return foo::N; //returns 3
}
怎么回事?
由于显然已声明但未定义的变量的值不能在常量表达式中使用,因此constexpr
仅与变量的definition有关。 (当然,如果变量是内联的,则可能是因为它是声明为constexpr
的静态成员,所以every定义必须具有constexpr
。)这意味着const
(在变量本身上:constexpr char*
为char *const
,而不是const char*
),因此您没有更改变量的type。这与
// foo.hpp
extern const int x;
// foo.cpp
constexpr int x=2;
这也许不足为奇。
所以一切都很好!变量的值只能在包含定义的translation unit中用于常量表达式中,但这并不奇怪,并且可以轻松地将其解释为modularity的功能。 Clang的错误之处在于它有两个定义:大概是它试图忽略类中定义的constexpr静态数据成员的(自C ++ 17起不推荐使用)类外定义。