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

Cla*_*ius 6 c++ variant generic-lambda c++17

我想写一个通用的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);
}
Run Code Online (Sandbox Code Playgroud)

GCC很高兴从7.1版本开始编译此代码。另一方面,Clang抱怨the的arg.this_r == 0参数if constexpr不是常量,可以回溯到4.0.0版本,但是在当前trunk中仍然存在。

谁在这里,我该如何避免这个问题(假设一个简单的对象if不会被剪裁,因为两个分支之一都无法实例化)?

附录:argClang作为值而不是const左值引用传递,很高兴,但是不幸的是,这不是我的选择。

use*_*670 7

由于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);
}
Run Code Online (Sandbox Code Playgroud)

在线编译器