3

First time using Boost, and trying to grok how to use boost::variant. Please find below an example program and the error message (GCC v5.3.0, -std=c++14)

#include <vector>
#include <iostream>
#include <sstream>

#include <boost/variant.hpp>

using int_tree_t =
    boost::make_recursive_variant <
      int,
      std::vector<boost::recursive_variant_>>;

auto operator << (std::ostream& out, const int_tree_t& tree) ->
std::ostream&
{
  struct stringify :
    public boost::static_visitor <std::string>
  {
  public:
    auto operator () (int i) const ->
    std::string
    {
      return std::to_string (i);
    }

    auto operator () (const std::vector<int_tree_t>& vec) const ->
    std::string
    {
      std::stringstream ss;
      ss << "(";

      auto it = std::begin (vec);

      if (!vec.empty ()) {
        ss << *it;
      }

      for (; it != std::end (vec); ++it) {
        ss << " " << *it;
      }

      ss << ")";

      return ss.str ();
    }
  };

  std::stringstream ss;
  ss.flags (out.flags ());

  ss << boost::apply_visitor (stringify (), tree);

  return (out << ss.str ());
}

Error message:

In file included from /usr/local/include/boost/variant/apply_visitor.hpp:16:0,
                 from /usr/local/include/boost/variant/detail/hash_variant.hpp:23,
                 from /usr/local/include/boost/variant/variant.hpp:34,
                 from /usr/local/include/boost/variant.hpp:17,
                 from test2.cpp:5:
/usr/local/include/boost/variant/detail/apply_visitor_unary.hpp: In instantiation of ‘typename Visitor::result_type boost::apply_visitor(const Visitor&, Visitable&) [with Visitor = operator<<(std::ostream&, const int_tree_t&)::stringify; Visitable = const boost::make_recursive_variant<int, std::vector<boost::recursive_variant_, std::allocator<boost::recursive_variant_> > >; typename Visitor::result_type = std::__cxx11::basic_string<char>]’:
test2.cpp:50:43:   required from here
/usr/local/include/boost/variant/detail/apply_visitor_unary.hpp:84:43: error: ‘const struct boost::make_recursive_variant<int, std::vector<boost::recursive_variant_, std::allocator<boost::recursive_variant_> > >’ has no member named ‘apply_visitor’
     return visitable.apply_visitor(visitor);
                                           ^

If I understand correctly, boost::make_recursive_variant is supposed to create a type which acts identical to boost::variant... but the error message appears to indicate that it doesn't have the apply_visitor function, which is necessary for visitation. I've read over [this(http://www.boost.org/doc/libs/1_60_0/doc/html/variant/tutorial.html) page, but there's nothing there about having to use a "special" visitation pattern with recursive variants.

How should I be writing this program?

Piotr Skotnicki
  • 46,953
  • 7
  • 118
  • 160
Arandur
  • 727
  • 6
  • 19

1 Answers1

4

make_recursive_variant is a metafunction, not a type in its own right. So you have to evaluate the metafunction:

using int_tree_t =
    boost::make_recursive_variant <
      int,
      std::vector<boost::recursive_variant_>>::type;
                                             ↑↑↑↑↑↑

Otherwise, you're using a metafunction type instead of a variant type.

Barry
  • 286,269
  • 29
  • 621
  • 977