Reputation: 4303
Suppose I have an overload set, like so:
class C
{
public:
static void f(const A &);
static void f(const B &);
};
I'd like to do something like
std::variant<A, B> v;
// ...
std::visit(C::f, v);
but this doesn't compile. Is there some way of taking an overload set and regarding it as, or converting it to, a Visitor?
Upvotes: 3
Views: 363
Reputation:
If you can make an instance of class C
, you could overload the member operator()
on class C
to call the appropriate function based on the variant type:
#include <iostream>
#include <variant>
struct A {};
struct B {};
class C
{
public:
template <typename T>
void operator()(const T& t) { C::f(t); }
static void f(const A &) { std::cout << "A\n"; }
static void f(const B &) { std::cout << "B\n"; }
};
int main()
{
std::variant<A, B> v_a = A{};
std::variant<A, B> v_b = B{};
C c;
std::visit(c, v_a); // "A"
std::visit(c, v_b); // "B"
return 0;
}
Upvotes: 1
Reputation: 25387
If you already use Boost, Boost.HOF has a utility to wrap an overload set for you: BOOST_HOF_LIFT
:
std::visit(BOOST_HOF_LIFT(C::f), v);
Upvotes: 2
Reputation: 4303
Actually, after playing around with this further I've realized that I can do
std::visit([](const auto & t) { C::f(t); }, v);
so I'll leave this here as a potential solution for anyone else with the same problem.
Upvotes: 5