constexpr 函数的常量引用参数:gcc/msvc vs clang/icc

const reference argument of constexpr function: gcc/msvc vs clang/icc

本文关键字:msvc vs clang icc gcc 函数 常量 引用 参数 constexpr      更新时间:2023-10-16

我发现使用常量引用参数调用constexpr静态方法会导致clang和icc的错误"表达式不是整数常量",但对于gcc或msvc(https://godbolt.org/z/PewOVc(则不然:

struct S
{
static constexpr bool ok() { return true; }
};
constexpr void ff(const S &s) // OK for everyone if not a ref
{  
static_assert(s.ok(), "oops!"); // ERROR clang/icc, OK gcc/msvc  
static_assert(S::ok(), "oops!"); // OK for everyone
}

如果参数不是引用,则代码由这些编译器中的任何一个编译。谁在这里是对的/正确的?

C++ 标准取消具有引用类型的计算 id 表达式参与常量表达式的资格(除非满足更多约束,而此代码并非如此(。

然而,海湾合作委员会似乎忽略了这一规则。使用这个简化函数可以获得相同的结果(gcc 接受,clang 拒绝(:

constexpr void ff(const int &s) 
{  
static_assert((s, true), "oops!"); 
}

所以这个问题与静态成员函数无关。我的解释是这是一个 gcc 错误。

我没有检查msvc,也许那里的错误不同,但它仍然是错误的。