带有 boost::variant 的 operator&lt;&lt; 是如何实现的(How operator<< with boost::variant is implemented)

问题

我知道boost::variant是这样实现的

template <typename... Vs>
struct variant {
    std::aligned_union<Vs...>::type buffer;
    ....
};

我们如何为这样的结构创建一个operator<<来打印存储在缓冲区中的类型并将其传递给operator<<用于cout ? 为此,我们需要知道存储在缓冲区中的元素的类型,对吧? 有没有办法知道这一点?

我也在寻找这种实现的解释,如果存在的话。 不仅仅是它存在以及我如何使用它。

回答1

Boost 有一个 apply_visitor 函数,它接受一个通用函数对象并将变体的类型传递给它。 所以实现operator<<就像这样简单:

template <class... Ts>
std::ostream& operator<<(std::ostream& os, boost::variant<Ts...> const& var) {
    return boost::apply_visitor(ostream_visitor{os}, var);
}

和:

struct ostream_visitor : boost::static_visitor<std::ostream&>
{
    std::ostream& os;

    template <class T>
    std::ostream& operator()(T const& val) {
        return os << val;
    }
};

或者简单地说:

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);
}

您可以在本教程中看到一些其他示例。


更多相关内容:请点击查看