Great feedback so far. Thanks! If I know what I'm talking about then, typeswitch != overload resolution typeswitch != static_visitor When a programmer uses overload resolution, it's more like: "Mr. Compiler, here are a bunch of functions named identically. Select the best one based on the parameter I have here. Feel free to do some reasonable conversions along the way," When a programmer uses a typeswitch, it's more like: "Hey typeswitch, here are a bunch of typecases I want you to match exactly to the parameter. If none of them match, don't bother calling any. So, no conversions, please. If you see a default typecase (i.e., a lambda wrapped in an "otherwise" functor) use that one if you don't find an exact match". Example: void func(std::string); void func(double); int var; func(var) // calls func(double) as per overload resolution. on the other hand, match(var)( [](std::string) { std::cout << "Ok string\n"; }, [](double) { std::cout << "Ok double\n"; }, otherwise([](auto something){ std::cout << "don't know\n"; }) ); prints "don't know". This is expected and desirable when I have my typeswitch hat on. Some may wonder if this is a right design choice. Well, that's the point, it is a choice. If you need good old overload resolution, the language has it and you have an option of using boost.OverloadFunction library when needed. (pretty cool library btw). I see no reason to duplicate that. typeswitch is also quite different from the static_visitor because typeswitch does not statically check if all the possible cases are handled. boost.variant static_visitor does that. That's great when you want it. But in the case of boost.any (also poco::dynamic_any), no compile-time solution is possible. In the above match example, I don't think twice if var were a boost.any. I would naturally expect otherwise clause being called because the any has an integer and the specific typecases don't match an int. The typeswitch library is also applicable to polymorphic class hierarchies. The tests (dynamic_cast) must be performed at run-time in that case.
The only issue I immediately see with the overload implementation is that it will require special handling if someone passes in a function pointer, which is a perfectly valid function object so you'd expect it to just work as a user of match. That said, support for function pointers would still be very easy to add in, it's just something that shouldn't be forgotten.
As this is not an yet another overload implementation, there is probably less need to support function pointers. That support is already available in boost.function_overload. Furthermore, you could simply wrap a function pointer in lambda typecase.
.... This would be extremely useful for creating boost::variant visitors right at the apply_visitor call-site.
Certainly. Such capability belongs in boost.variant where all the visit cases will be enforced statically.
The bug is probably just worked around by using "using operator()". When I was experimenting with that kind of thing, it worked just fine.
Right. Any idea how to use the using syntax with variadic parameters. I
tried the following which did not work.
template
You could wrap lambdas into proper function objects to work around this.
That's what the "otherwise" clause does in my implementation of match.
... cannot use generic code etc
Again, the "otherwise" clause is a good place to use a generic lambda if that's what you meant.
Getting a reasonable, deduced return type should be easy with decltype and common_type (really, apply_visitor should probably do this if it hasn't been updated to do so already, using the explicit result_type instead only if it is specified, and allowing the return type to be an explicit template argument to apply_visitor).
Interesting! Let me think more on that a bit. As of now, anything that the
typecase lambdas return is simply tossed away.
R/ Sumant
On 30 November 2013 09:46, Matt Calabrese
On Sat, Nov 30, 2013 at 5:11 AM, Mathias Gaunard < mathias.gaunard@ens-lyon.org> wrote:
AFAIK variant doesn't require that your visitors inherit from
static_visitor, just that they define the result_type typedef.
Well, whatever the current requirement is specified as, it would be nice if this utility met that requirement. Being able to easily write variant visitors at the call-site is very useful. Getting a reasonable, deduced return type should be easy with decltype and common_type (really, apply_visitor should probably do this if it hasn't been updated to do so already, using the explicit result_type instead only if it is specified, and allowing the return type to be an explicit template argument to apply_visitor). Anything that makes variants easier to use is a great addition to boost, IMO.
-- -Matt Calabrese
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost