2015-01-08 17:39 GMT+08:00 TONGARI J
2015-01-08 3:14 GMT+08:00 Matt Calabrese
: On Wed, Jan 7, 2015 at 10:48 AM, Peter Dimov
wrote: Matt Calabrese wrote:
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.
Hmm. If you had a reference_wrapper<F> which SFINAEd its operator() on whether F::operator() compiles, could you not then pack those reference wrappers into an overloads object?
Unfortunately, no, because at that point you've "flattened" the operator() to having all template parameters. Overload resolution would no longer be able to produce better or worse matches when one or more of the passed-in function objects are callable. For instance, if you pass in tie_overloads( [](int a) {}, [](auto a) ) to apply_visitor, if the variant contained an "int" then the function call would actually be ambiguous rather than preferring the int overload since both overloads are callable and now just have template parameters as arguments. I've put a lot of thought (on/off for years) into trying to come up with a tie_overloads that actually works precisely as an overload set and I'm reasonably certain that it cannot be done, but I am unable to say that for certain.
On the plus side, I've never actually found the lack of a tie_overloads to be a problem, since in times that I've personally wanted it it's been easy to manually make a reference-semantic function object at the call-site via lambdas. The main difficulty is that this just can't be done automatically inside of generic code, so the value-semantics of the function object passing sometimes bleeds out to the user a little bit in generic code (the user just needs to be aware the function objects are copied/moved in). In practice this isn't much of a problem since standard library algorithms take function objects by value anyway and so people are familiar with those semantics.
At least, for functors that don't overload themselves (e.g. lambdas), you can do something like this: http://coliru.stacked-crooked.com/a/c38ed042f6b6b8a6
That said, I don't have such a need myself though, just for fun :p