Reputation: 386
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
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
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