Boost logo

Boost :

Subject: Re: [boost] [variant] match()
From: pfultz2 (pfultz2_at_[hidden])
Date: 2015-01-07 16:49:34


> 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.

Also, additionally, the Fit library provides the `fit::conditional` which
find
the first match(whereas `fit::match` finds the best match). So by the nature
of how it works, it can be used even when the functions are flattened. So if
you wanted to use references you could do this instead:

apply_visitor( fit::conditional(
    std::ref([](A & a){ cout << "it's a A!"; }),
    std::ref([](B & b){ cout << "oh, a B!"; }),
    std::ref([](C & c){ cout << "ah yes, a C!"; }),
    std::ref([](auto & d){ cout << "a default!"; })
), v);

Of course the semantics are different. Ultimately, `fit::conditional` is
designed for overloading with conditional constraints like this:

#define IF(...) typename std::enable_if<(__VA_ARGS__), int>::type = 0

apply_visitor( fit::conditional(
    [](auto & range, IF( is_range<decltype(range)>() )){ cout << "it's a
range"; },
    [](auto & sequence, IF( is_sequence<decltype(sequence)>() )){ cout <<
"oh, a sequence!"; },
    [](auto & d){ cout << "a default!"; }
), v);

Which is equivalent to the following:

apply_visitor( fit::conditional([](auto& x)
{
    using T = decltype(x);
    if (is_range<T>()) cout << "it's a range";
    else if (is_sequence<T>()) cout << "oh, a sequence!";
    else cout << "a default!";
}), v);

Hence the name conditional.

Paul

--
View this message in context: http://boost.2283326.n4.nabble.com/variant-match-tp4670714p4670760.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk