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.
Boost. Variant, part of collection of the Boost C++ Libraries. It is a safe, generic, stack-based discriminated union container, offering a simple solution for manipulating an object from a heterogeneous set of types in a uniform manner.
boost::apply_visitor — Allows compile-time checked type-safe application of the given visitor to the content of the given variant, ensuring that all types are handled by the visitor.
boost::variant is conceptually similar to what you've done before, but by not literally using a union and instead taking a manual approach to placement construction/destruction of objects in its buffer (while handling alignment issues explicitly) it works around the restrictions that C++ has re complex types in actual ...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With