Clang 声称通用 lambda 参数的 constexpr 成员不是 constexpr

Clang claims constexpr member of generic lambda argument is not 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 很乐意从大约 version 7.1. Clang, on the other hand, complains that the arg.this_r == 0 argument to the if constexpr is not constant, going back to version 4.0.0 but this is still present in the current trunk.

开始编译此代码

谁在右边,我怎样才能避免这个问题(假设一个简单的 if 不会削减它,因为两个分支之一不可实例化)?

附录:传递 arg 作为值而不是 const 左值引用,Clang is happy,但不幸的是这不是我的选择。

由于 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);
}

online compiler