I'd like to investigate boost::spirit::karma::generate as a replacement for std::stringstream for a boost::variant containing, apart from familiar types such as int and double, one or more custom classes (e.g. A). However I'm unable to even compile the code once I include one or more custom classes in the variant.
#include <iostream>
#include <boost/spirit/include/karma.hpp>
#include <boost/variant.hpp>
struct A {
double d;
explicit A(const double d) : d(d) {}
friend std::ostream& operator<<(std::ostream& os, A const& m) {
return os << "{" << m.d << "}";
}
};
BOOST_FUSION_ADAPT_STRUCT(A, d)
using Variant = boost::variant<int, double, A>;
void test_stringstream(const Variant &v) {
std::stringstream os;
os << v;
std::cout << os.str() << std::endl;
}
void test_karma(const Variant &v) {
std::string str;
boost::spirit::karma::generate(std::back_inserter(str), v);
std::cout << str << std::endl;
}
int main() {
A a(double(1.0));
std::cout << a << std::endl;
test_stringstream(Variant(a));
test_karma(Variant(a));
}
I'd expect the output:
{1}
{1}
{1}
The error output begins with
mpl_iterator.hpp:45:24: error: no matching constructor for initialization of 'boost::fusion::mpl_iterator<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<1>, A, boost::mpl::l_end>>>::deref<boost::fusion::mpl_iterator<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<1>, A, boost::mpl::l_end>>>>::type' (aka 'A')
return type();
Apart from custom classes, I'd also like to enquire how one could make Enums 'streamable' as it were via boost::spirit::karma::generate.