Boost logo

Boost :

Subject: Re: [boost] [Boost.Variant] Parameterized Visitors
From: Andy Jost (Andrew.Jost_at_[hidden])
Date: 2012-01-13 12:10:58


> bind<result_type>(my_visitor1(), 1, 3.14, 'k', _1)?

Thanks (Duh)! I hadn't considered that a binder would meet the visitor requirements, but in retrospect it seems obvious.

The tie and load methods are more visually appealing (to me, anyway), but maybe not enough so as to motivate any more work along these lines.

Compare:

        apply_visitor(my_visitor1().tie(1, 3.14, 'k', this->a_vector), abc);

versus

        apply_visitor(bind(my_visitor1(), 1, 3.14, 'k', ref(this->a_vector), _1), abc);

-Andy

-----Original Message-----
From: boost-bounces_at_[hidden] [mailto:boost-bounces_at_[hidden]] On Behalf Of Steven Watanabe
Sent: Thursday, January 12, 2012 6:42 PM
To: boost_at_[hidden]
Subject: Re: [boost] [Boost.Variant] Parameterized Visitors

AMDG

On 01/12/2012 04:30 PM, Andy Jost wrote:
> New poster.
>
> When I'm using Boost.Variant, I often want to pass additional parameters to a visitor. A common case is when the variant is a class member and I want to have access to other members (or even "this") in the visitor.
>
> I muddled through for a long time writing visitors with explicit constructors and data members to take whichever parameters I needed, but I finally got around to making this generic with Boost.Fusion and I love it. I'm wondering whether I should submit this for consideration as an addition to the Boost.Variant library and how.
>
> First a few questions:
>
> 1. Is there already an equivalent solution that I should be aware of?
>

bind<result_type>(my_visitor1(), 1, 3.14, 'k', _1)?

> 2. Should this be considered for an addition to Boost?
>
> 3. If so, how do I begin the review process?
>
> 4. This is a small change (400 or so lines of code). Is there anyone willing to help with the logistics, testing, and/or documentation (perhaps in exchange for a credit in the docs)?
>
> Here's an example, which should be fairly self-explanatory:
>
> struct A {}; struct B {}; struct C {};
>
> struct my_visitor1 : param_visitor<my_visitor1, bool>
> {
> result_type operator()(int, float, char, A) const {...}
> result_type operator()(int, float, char, B) const {...}
> result_type operator()(int, float, char, C) const {...}
> };
>
> struct my_visitor2 : fused_param_visitor<my_visitor2, bool>
> {
> template<typename Sequence>
> result_type operator()(Sequence const &, A) const {...}
> ...
> };
>
> int main()
> {
> boost::variant<A,B,C> abc;
> boost::apply_visitor(my_visitor1().tie(1, 3.14, 'k'), abc);
> boost::apply_visitor(my_visitor2().tie(1, 3.14, 'k'), abc);
> return 0;
> }
>
> In terms of technical detail, there's not much to it. The base classes provide tie() and load() methods to take arguments by reference or value, respectively. A call to one of those returns a helper object that contains a copy of the derived visitor and a fusion::vector of arguments. Visiting that causes the user-defined visitor to be called with all of the arguments. For parameter forwarding, I use an implementation of perfect forwarding based on boost/flyweight/detail/dyn_perfect_fwd.hpp (I used a default limit of 4 parameters).
>

In Christ,
Steven Watanabe

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


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