On Wed, Jan 7, 2015 at 12:41 AM, Eelis
Boost.Variant provides access through get() and visitors, but in C++11 we can do so much better! :)
For a boost::variant, the attached small utility function match() lets you write:
match(v, [](A & a){ cout << "it's a A!"; } [](B & b){ cout << "oh, a B!"; } [](C & c){ cout << "ah yes, a C!"; });
Return values are supported. I think this really belongs in Boost. It makes variants much more usable.
Regards,
Eelis
This has come up before in various contexts. I'm not a fan of "match" as it is implemented here for a few of reasons: * It does not allow one or more of the functions to work with multiple elements (I.E. if one of them is an lambda with an auto parameter). * It does not currently scale to n-ary visitation. * This implementation is linear and uses variant's get rather than simply re-using apply_visitor. * Directly common_type is probably not what you want here due to its behavior regarding references and because it is potentially order-dependent. My personal stance and I what I use on projects is something a little different and I try to evangelize: Make an overloads template that just works with apply_visitor or an apply_visitor like function: apply_visitor( overloads( [](A & a){ cout << "it's a A!"; } [](B & b){ cout << "oh, a B!"; } [](C & c){ cout << "ah yes, a C!"; } [](auto & d){ cout << "a default!"; } ), v ); All overloads does is make a visitor that contains an overload set of all of the passed-in function objects (done by base classes and bringing in the operator() functions from each base). Instead of this solution having its own dispatching mechanism it just works via apply_visitor so it has exactly the known behavior and works fine with n-ary visitation out of the box. Overload resolution is exactly C++ overload resolution in an overload set because each passing in function object's operator() is brought in through a using-declaration. Function objects that are function pointers are handled as well via internal wrapping. The main limitation of this approach is that overloads must copy/move the passed-in function objects. I.E. there is no known tie_overloads that would be able to exhibit the same behavior. -- -Matt Calabrese