c++ - Clang 声称通用 lambda 参数的 constexpr 成员不是 constexpr
问题描述
我想写一个通用的 lambda 作为一个变体的访问者。这个变体的成员包含一个 constexpr 成员值,我想在访问者中使用它。例如:
#include <variant>
template<int r>
struct S {
constexpr static int this_r = r;
};
int f(std::variant<S<0>, S<1>, S<2> > v) {
return std::visit([](auto const& arg) {
if constexpr(arg.this_r == 0) { return 42; }
else { return arg.this_r; }
}, v);
}
int g() {
std::variant<S<0>, S<1>, S<2> > x = S<2>();
return f(x);
}
GCC 很高兴从7.1 版开始编译此代码。另一方面,Clang 抱怨arg.this_r == 0
参数if constexpr
不是恒定的,回到版本 4.0.0但这仍然存在于当前的 trunk中。
谁在这里正确,我该如何避免这个问题(假设一个简单if
的不会削减它,因为两个分支之一是不可实例化的)?
附录:arg
作为值而不是 const 左值引用传递,Clang很高兴,但不幸的是,这不是我的选择。
解决方案
由于this_r
它是一个静态成员,因此您始终可以在不取消引用(非 constexpr)对象实例的情况下访问它,以使 clang 或其他编译器满意:
int f(std::variant<S<0>, S<1>, S<2> > v) {
return std::visit([](auto const& arg) {
if constexpr(::std::remove_reference_t<decltype(arg)>::this_r == 0) { return 42; }
else { return ::std::remove_reference_t<decltype(arg)>::this_r; }
}, v);
}
推荐阅读
- javascript - UseEffect 不会使用更新的状态
- jenkins - 在 CentOS 7 上安装 Jenkins 时无法启动
- python - 迭代字典时Django模板未检测到某些键
- string - Haskell:字符串中最后两个整数的总和
- r - 如何在创建条件R时使用级别而不是标签
- chat - Mesibo SDK:1对1聊天:语音笔记功能Android
- javascript - 将对象键重命名为不同格式的方法
- javascript - 获取当前 Observable 状态的值
- python - Python matplotlib如何抑制科学计数法中的浮点数以节省ylabel的空间
- java - 如何将一些元素添加到从具有某些方法的类创建的堆栈中