|
Boost : |
Subject: Re: [boost] [variant] match()
From: Matt Calabrese (rivorus_at_[hidden])
Date: 2015-01-07 14:14:11
On Wed, Jan 7, 2015 at 10:48 AM, Peter Dimov <lists_at_[hidden]> 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.
> And on another note, even if we had the overloads() function template, it
> would still make sense to me to have something like match( ... ) that is
> just an alias for apply_visitor( overloads( ... ) ). I would even make it a
> member, in which case it would probably be more properly called 'apply'.
> :-)
True. There is also one thing that I do like about match -- it's possible
to make one that requires an /exact/ match (I.E. in places where you want
to handle each case individually and don't want overload resolution, more
similar to a type switch). So both match (generalized for the n-ary case)
and overloads still seem useful in different scenarios. I know another
booster on this list has implemented this, though I don't think it's been
posted.
-- -Matt Calabrese
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk