Boost logo

Boost Users :

From: Felipe Magno de Almeida (felipe.m.almeida_at_[hidden])
Date: 2007-01-18 20:19:27


On 1/18/07, cdr_at_[hidden] <cdr_at_[hidden]> wrote:
> Hello,
>
> Why does boost::apply_visitor take a const reference to the visitor object? This forces me to write a
> boost::static_visitor-derived visitor that looks like this:
>
> class my_visitor_t : public boost::static_visitor<>
> {
> template <typename T> void operator()(T const& t) const
> { // do something ... }
>
> };
>
> ... when what I would really like to do is something like this:
>
> class my_visitor_t : public boost::static_visitor<>
> {
> my_visitor(my_data & _data) : data(_data) {}
>
> void operator()(int const& i) // NOT const
> { // data.blah.blah = // blah }
>
> template <typename T> void operator()(T const& t) // NOT const
> { // data.foo() }
>
> my_data & data
>
> };
>
> So I might have several different instances of a given a my_variant_t:
>
> my_variant_t v1;
> my_variant_t v2;
> my_variant_t v3;
>
> my_data_t my_data;
>
> my_visitor_t my_visitor(my_data);
>
> boost::apply_visitor(my_visitor, v1);
> boost::apply_visitor(my_visitor, v2);
> // and so on...
>
> ... BUT, the fact that I must make the visitor operator() const makes this impossible and is inconsistent with the way that I'm
> used to leveraging visitors in the BGL. Would someone be kind enough to comment on the rationale behind this? What am I missing
> here?

Assuming you dont want to return the results of the execution of the
visitor into my_data, but to really use it in a non-const way, why
dont you do something like this:

struct my_visitor
{
  typedef void result_type;

  void operator()(int const&, data&) const
  {
  }

  template <typename T>
  void operator()(T const&, data&) const
  {
  }
};

my_visitor v;

boost::apply_visitor(boost::bind(v, my_data), v1);

Now, if you want to return from the visitor, you should use:

struct visitor
{
  typedef data result_type;

  data operator()(int const&) const;
  template <typename T>
  data operator()(T const&) const;
};

data d = boost::apply_visitor(visitor(), v1);

It have worked for me for a time.

>
> - Thanks
>
> Chris
>

Best regards,

-- 
Felipe Magno de Almeida

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net