|
Boost : |
Subject: [boost] [Boost.Variant] Parameterized Visitors
From: Andy Jost (Andrew.Jost_at_[hidden])
Date: 2012-01-12 19:30:55
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?
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).
Thanks,
Andy
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk