Boost logo

Boost :

Subject: Re: [boost] A more convenient Variant visitation syntax
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2012-04-14 14:26:11


On Sat, Apr 14, 2012 at 9:39 AM, Thomas Heller
<thom.heller_at_[hidden]>wrote:

> On Sat, Apr 14, 2012 at 5:41 PM, Mathias Gaunard
> <mathias.gaunard_at_[hidden]> wrote:
> > On 14/04/12 17:00, Kevin Wu Won wrote:
> >>
> >> While Boost Variant is a wonderful library that fills a genuine hole
> >> in the C++ language, it is not as nice to use as it could be. The
> >> "correct" way to unwrap a variant is to apply a static visitor, but
> >> this method carries a high syntactic burden because it needs the user
> >> to define a class (probably somewhere far away) just so they can
> >> "switch" on the type of the object stored in the variant.
> >>
> >> I came up with a solution where the handler functions can be specified
> >> inline with C++11 lambdas. Here's an example:
> >>
> >> boost::variant< int, std::string> u("hello world");
> >> int result = match(u,
> >> [](int i) -> int { return i; },
> >> [](const std::string& str) -> int { return str.length(); });
> >>
> >>
> >> The `match` function accepts the variant followed by the handler
> >> functions. The functions can be specified in any order. It will fail
> >> to compile if the functions do not match the types of the variant, if
> >> the return types are not all the same, or if a non-unary function is
> >> supplied.
> >>
> >> This is C++11 only because it's quite pointless without lambda
> >> functions. I've tested it with gcc 4.7. It doesn't work on gcc 4.6,
> >> which can't handle the variadic templates.
> >
> >
> > It can be done in C++03 and expression-template-based lambdas just fine
> as
> > well.
> >
> > All you need to do is generate a function object that inherits
> recursively
> > from a set of other function objects.
> >
> > The function objects in question need to be either monomorphic or to be
> > sufficiently constrained with SFINAE so that each operator() overload is
> not
> > ambiguous.
> >
> > Unfortunately, Boost.Phoenix was never extended to support this.
>
> I really like the idea, and i think the C++11-based solution above is
> nice! I didn't have the time yet to glance through the code though ...
>
> Phoenix didn't tackle that yet because it is a hard problem ... the
> main problem is the syntax how to express which lambda is responsible
> for what types. The above solution with C++11 lambdas is nice indeed!
> However, what's missing is something like a "catch all" aka a
> templated lambda ...
> FWIW, independent of this thread I wanted to tackle that for the next
> release ... I'd like to see some propositions on how such a type
> based matching could be done with phoenix, which might come down to
> have something like pattern matching in functional languages ... I
> have no idea how to to do that yet ....
>

Doesn't Lorenzo's Overload (or whatever name it is now) (sub)library
effectively do this already? I.e., it packages up a bunch of function
objects and dispatches to the (first?) one that can handle the give
argument type?

- Jeff


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