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

问题描述 投票:5回答:1

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

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
}

怎么回事?

c++ initialization c++17 constexpr
1个回答
2
投票

由于显然已声明但未定义的变量的值不能在常量表达式中使用,因此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起不推荐使用)类外定义。

© www.soinside.com 2019 - 2024. All rights reserved.