考虑一个具有常量成员的类:
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
}
怎么回事?
答案 0 :(得分:2)
由于显然已声明但未定义的变量的值不能在常量表达式中使用,因此constexpr
仅与变量的定义有关。 (当然,如果变量是内联的,则可能是因为它是声明为constexpr
的静态成员,所以每个定义都必须具有constexpr
。)它意味着const
(变量本身:constexpr char*
是char *const
,而不是const char*
),因此您没有更改变量的 type 。这和
// foo.hpp
extern const int x;
// foo.cpp
constexpr int x=2;
这也许不足为奇。
一切都很好!变量的值只能在包含定义的翻译单元中用在常量表达式中,但这并不奇怪,可以轻松地将其解释为模块化的功能。 Clang的错误之处在于它有两个定义:大概是它试图忽略类中定义的constexpr静态数据成员的(自C ++ 17起不推荐使用)类外定义。