Assaf Muller
Assaf Muller

Reputation: 386

How to print a boost::variant of streamable types?

I feel like I'm having a serious 'Doh!' moment here...

I'm currently trying to implement:

std::ostream& operator<<(std::ostream &out, const MyType &type)

Where MyType holds a boost::variant of int, char and bool. IE: Make my variant streamable.

I tried doing this:

out << boost::apply_visitor(MyTypePrintVisitor(), type);
return out;

And MyTypePrintVisitor has a templated function that uses boost::lexical_cast to convert the int, char or bool to a string.

However, this doesn't compile, with the error that apply_visitor is not a function of MyType.

I then did this:

if(type.variant.type() == int)
out << boost::get<int> (type.variant);
// So on for char and bool
...

Is there a more elegant solution I'm missing? Thanks.

Edit: Problem solved. See the first solution and my comment to that.

Upvotes: 6

Views: 3402

Answers (2)

user2146414
user2146414

Reputation: 1038

Not sure why but this does not work with clang 5.0 with C++17. But I've another solution:

std::variant<int, char, bool> v;
std::visit(
    [](auto value) { std::cout << value << std::endl; },
    v
);

Upvotes: 1

Mike Seymour
Mike Seymour

Reputation: 254461

You should be able to stream a variant if all its contained types are streamable. Demonstration:

#include <boost/variant.hpp>
#include <iostream>
#include <iomanip>

struct MyType
{
    boost::variant<int, char, bool> v;
};

std::ostream& operator<<(std::ostream &out, const MyType &type)
{
    out << type.v;
}

int main()
{
    MyType t;
    t.v = 42;
    std::cout << "int: " << t << std::endl;

    t.v = 'X';
    std::cout << "char: " << t << std::endl;

    t.v = true;
    std::cout << std::boolalpha << "bool: " << t << std::endl;
}

Output:

int: 42
char: X
bool: true

If you do need to use a visitor (perhaps because some of the contained types aren't streamable), then you need to apply it to the variant itself; your snippet of code looks like it's applying it to a MyType object instead.

Upvotes: 7

Related Questions