首页 > 解决方案 > constexpr 函数的 const 引用参数:gcc/msvc vs clang/icc

问题描述

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

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++compiler-errorsc++14language-lawyer

解决方案


C++ 标准取消了具有引用类型的已评估 id 表达式参与常量表达式的资格(除非满足更多约束,但此代码不是这种情况)。

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

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

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

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


推荐阅读