Reputation: 21510
I understand that boost::variant
is implemented something like so
template <typename... Vs>
struct variant {
std::aligned_union<Vs...>::type buffer;
....
};
How can we make an operator<<
for a struct like this that prints the casts the type stored in the buffer and passes that to operator<<
for cout
? For this we would need to know the type of the element stored in the buffer right? Is there a way to know this?
Also I am looking for an explanation of such an implementation, if one exists. Not just that it exists and how I can use it.
Upvotes: 4
Views: 348
Reputation: 302738
Boost has an apply_visitor
function, that takes a generic function object and passes the type of the variant into it. So implementing operator<<
is as straightforward as:
template <class... Ts>
std::ostream& operator<<(std::ostream& os, boost::variant<Ts...> const& var) {
return boost::apply_visitor(ostream_visitor{os}, var);
}
with:
struct ostream_visitor : boost::static_visitor<std::ostream&>
{
std::ostream& os;
template <class T>
std::ostream& operator()(T const& val) {
return os << val;
}
};
Or simply:
template <class... Ts>
std::ostream& operator<<(std::ostream& os, boost::variant<Ts...> const& var) {
return boost::apply_visitor([&os](const auto& val) -> std::ostream& {
return os << val;
}, var);
}
You can see some other examples in the tutorial.
Upvotes: 5