0

In Java, I am able to define a variable of a generic class without specifying type.

class Tree<T extends Comparable<? super T>> {}
somewhere-else: Tree tree;

I can then read in some object from a file and type-cast it to the class type I desire.

tree = (Tree<String>) some object;

With boost::variant I have begun a variant definition.

typedef boost::variant<Tree<std::string>, Tree<int>> TreeVariant; TreeVariant tree;

I know I need to specify a visitor class but it is not clear from this example how to define it such that I am able to assign to my tree variable either Tree<std::string> or Tree<int>.

I would then like to proceed from there to call member functions of Tree using the variable tree.

Mushy
  • 2,535
  • 10
  • 33
  • 54

1 Answers1

5

There is no need to create a visitor for assigning values to a boost::variant. As shown in the Basic Usage section of the tutorial, you just assign the value:

TreeVariant tree;
Tree<std::string> stringTree;
Tree<int> intTree;
tree = stringTree;
tree = intTree;

As for calling member functions, you should use a visitor:

class TreeVisitor : public boost::static_visitor<>
{
public:
  void operator()(Tree<std::string>& tree) const
  {
    // Do something with the string tree
  }

  void operator()(Tree<int>& tree) const
  {
    // Do something with the int tree
  }
};

boost::apply_visitor(TreeVisitor(), tree);

You can also return values from a static_visitor, like so:

class TreeVisitor : public boost::static_visitor<bool>
{
public:
  bool operator()(Tree<std::string>& tree) const
  {
    // Do something with the string tree
    return true;
  }

  bool operator()(Tree<int>& tree) const
  {
    // Do something with the int tree
    return false;
  }
};

bool result = boost::apply_visitor(TreeVisitor(), tree);
reima
  • 2,076
  • 15
  • 22
  • Where would I call boost::apply_visitor? Is it supposed to be a member function of the visitor? I am uncertain about this. – Mushy Mar 27 '13 at 14:48
  • `boost::apply_visitor` is a free function in the `boost` namespace. The last line in the code example shows how to call it. – reima Mar 27 '13 at 15:49
  • 2
    Depending on your code, you could also make TreeVisitor have a template member function operator(), which accepts any type of Tree. This might be useful if the operations do not need to be aware of the data type within the tree. – Dave S Mar 27 '13 at 16:33
  • @reima How could I make it so that boost::apply_visitor allows me to return a bool through a function operator such as `bool operator() (Tree& tree) const`; – Mushy Mar 27 '13 at 17:44
  • @Mushy I've updated my answer with an example for returning values from a `static_visitor`. – reima Mar 27 '13 at 17:51
  • @reima One last question. If I desire to pass two parameters into into a function operator such as `void operator() (Tree& tree, int some_val, long some_initial_index);`, how am I passing in the arguments so the right function is called? – Mushy Mar 27 '13 at 18:54
  • @reima I think `boost::apply_visitor(boost::bind(TreeVisitor(),tree, val, initialIndex));` may do the trick but not sure ... discovered that from a detailed search. – Mushy Mar 27 '13 at 19:13
  • @Mushy Add a constructor to `TreeVisitor` which takes the additional parameters and stores them in member variables. Then you can access them from `operator()`. – reima Mar 28 '13 at 14:16