静态成员声明为const,但初始化为constexpr

时间:2019-12-30 21:54:59

标签: c++ initialization c++17 constexpr

考虑一个具有常量成员的类:

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
}

怎么回事?

1 个答案:

答案 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起不推荐使用)类外定义。