Boost logo

Boost :

From: Yuval Ronen (ronen_yuval_at_[hidden])
Date: 2006-09-06 12:52:01


Theodore Omtzigt wrote:
>
>
> Dear Boost list Gurus:

I'm definitely not a guru...

> I got stuck trying to write a binary visitation of a Boost.Variant that
> modifies one of the arguments, like so:
>
>
>
> typedef boost::variant<int, float> myVariant;
>
>
>
> class add : public boost::static_visitor<> {
>
> public:
>
> void operator()(myVariant& lhs, const myVariant& rhs)const {
>
> lhs += rhs;
>
> }
>
> };

but I do know that the whole point of the variant visitor is to
decompose the variant to its possible content types. In other words, the
arguments to operator() shouldn't be the variant, but the variant's types.

> This won't compile with an error indicated that the lhs reference that is
> not to 'const' cannot be bound to a non-lvalue. I don't understand this
> error message and the many function template instantiations that are given
> as reference for the compilation error.

The compiler tried to convert the myVariant's types (int and float) to
myVariant. It is possible to do such implicit conversion (myVariant has
the right c'tors), but not to a non-const reference. That's the usual
C++ rule.

> Furthermore, I haven't gotten any
> new ideas how to fix this in the past 2 hours, so I hope to turn to this
> list for possible solutions. How does one write a binary visitor for
> Boost.Variants that allow modification of its arguments? Or if that is not
> possible, how does one, generically, compute with boost::variants?

This is not tested at all, just thrown off my sleeve, but I hope it
might work. Not sure.

class add : public boost::static_visitor<> {
public:
     void operator()(int& lhs, const int& rhs) const {
         lhs += rhs;
     }
     void operator()(float& lhs, const int& rhs) const {
         lhs += rhs;
     }
     void operator()(int& lhs, const float& rhs) const {
         lhs += (int) rhs;
     }
     void operator()(float& lhs, const float& rhs) const {
         lhs += rhs;
     }
};

Be aware that there are two apply_visitor functions, one member and one
free, and it might be important to get the right one - the one that
needn't the variant be const.

Also notice the third operator(): if you wanted the opposite - convert
the int to float and store the plus result in the variant, thus changing
the type of the variant's content, then I don't know how to do it. I
mean, you could make the visitor derived from static_visitor<float>,
make the operators() return the result, and store it in the variant
later, but that would also make int+int result a float, which might be
not good for you...

HTH,
Yuval


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