Can't stream std::endl with overloaded operator<<() for std::variant

前端 未结 3 507
不思量自难忘°
不思量自难忘° 2020-12-14 07:47

This answer describes how to stream a standalone std::variant. However, it doesn\'t seem to work when std::variant is stored in a std::unorde

3条回答
  •  死守一世寂寞
    2020-12-14 08:46

    For some reason, your code (which looks correct to me) is trying to instantiate std::variant<> (empty alternatives) both in clang and gcc.

    The workaround I found is to make a template for a specifically non-empty variant. Since std::variant cannot be empty anyway, I think it is usually good to write generic functions for non-empty variants.

    template
    std::ostream& operator<<(std::ostream& os, const std::variant& v)
    {
        std::visit([&os](auto&& arg) {
            os << arg;
        }, v);
        return os;
    }
    

    With this change, your code works for me.


    I also figured out that if std::variant had a specialization of std::variant<> without a single-argument constructor, this problem would not have happened in the first place. See the first lines in https://godbolt.org/z/VGih_4 and how it makes it work.

    namespace std{
       template<> struct variant<>{ ... no single-argument constructor, optionally add static assert code ... };
    }
    

    I am doing this just to illustrate the point, I don't necessarely recommend doing this.

提交回复
热议问题