1

If I have a discriminated union and want to write a function piecewise, the following code works just fine, but is taking advantage of some fairly tricky (at least to me) stuff involving overload groups:

struct A { };

struct B { };

typedef std::variant<A, B> C;

void f(const A & a) { std::cout << "a" << std::endl; }

void f(const B & b) { std::cout << "b" << std::endl; }

void f(const C & c) { std::visit([](const auto & x){ f(x); }, c); }

Is this a recommended way of doing things? Once it's actually written it seems superior to, say, writing something using holds_alternative.

I have tried to look up what people suggest online, but most of the examples I've seen that make use of std::visit involve writing literal pages of incomprehensible boilerplate to create visitor classes.

Daniel McLaury
  • 352
  • 1
  • 7

1 Answers1

2

Is this a recommended way of doing things?

Yes, that's a fairly normal way of visiting an overloaded function. The issue it solves is that f doesn't denote an object, but instead an overload-set of functions. Wrapping it in a lambda expression gives you an object.

The only slightly strange thing in that example is you include void f(const C & c) in the overload set. If you miss a case in the variant, you will end up with an infinite recursion if you try to visit that alternative.

involve writing literal pages of incomprehensible boilerplate

I'm not sure what you have found, but the other normal way isn't pages of boilerplate, either a generic lambda or an "overload" functor from constituent lambdas.

Caleth
  • 10,519
  • 2
  • 23
  • 35