consteval 声明不匹配适用于 MSVC,但不适用于 GCC 和 Clang

Ala*_*lan 5 c++ language-lawyer c++20

我编写了以下程序,该程序使用 msvc 编译,但不使用 gcc 和 clang 编译。演示

template<int x>
struct X {
consteval static int get();
int f() const;
};
//compiles with msvc but not with gcc and clang 
template<int x> int X<x>::get(){ return x; }  


int main() {
  constexpr int i = X<4>::get(); 
}
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,MSVC 编译了上面的演示,而 GCC 和 Clang 拒绝了它。海湾合作委员会 说:

template<int x>
struct X {
consteval static int get();
int f() const;
};
//compiles with msvc but not with gcc and clang 
template<int x> int X<x>::get(){ return x; }  


int main() {
  constexpr int i = X<4>::get(); 
}
Run Code Online (Sandbox Code Playgroud)

我想知道根据 C++20 标准,哪个编译器在这里是正确的。

Sto*_*ica 8

MSVC 默默地接受这个代码是错误的。这是不符合要求的,因此如果它提供扩展,它至少应该打印诊断信息(但我怀疑它由于错误而被接受)。

[dcl.constexpr]

1 如果函数或函数模板的任何声明具有 constexpr 或 consteval 说明符,则其所有声明应包含相同的说明符。

IIUC 这条规则的存在是由于一些 ODR 相关的影响。因此,GCC/Clang 直接拒绝它更为合理。