I would like to write a generic lambda as a visitor for a variant. The members of this variant contain a constexpr member value, which I would like to use in the visitor. For example:
#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 is happy to compile this code starting from about 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.
Who is in the right here and how could I avoid this issue (assuming that a simple if
does not cut it because one of the two branches is not instantiable)?
Addendum: Passing arg
as a value instead of a const lvalue reference, Clang is happy, but unfortunately this is not an option for me.
Since this_r
is a static member you can always access it without dereferencing (non constexpr) reference to object instance to make clang or other compilers happy:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With