How to print boost::any to a stream?

前端 未结 9 1302
悲哀的现实
悲哀的现实 2020-12-03 07:48

I have a Map std::map, which comes from the boost::program_options package. Now I would like to print the content o

9条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-03 08:07

    The list of type switches proposed in other answers can be improved with a loop over a type list using Boost MPL (see documentation of mpl::for_each and mpl::vector). The following code defines an operator<< for any boost::any that is given in the type list SupportedTypes and throws an exception otherwise.

    #include 
    #include 
    #include 
    
    #include 
    
    #include 
    #include 
    #include 
    
    class StreamInserter
    {
    private:
        std::ostream& os_;
        const boost::any &v_;
        mutable bool has_printed_;
    
    public:
        struct UnsupportedType {};
    
        StreamInserter(std::ostream& os, const boost::any &v)
            : os_(os), v_(v), has_printed_(false) {}
    
        template 
        void operator()(const T&) const
        {
            if (!has_printed_ && v_.type() == typeid(T))
            {
                os_ << boost::any_cast(v_);
                has_printed_ = true;
            }
        }
    
        void operator()(const UnsupportedType&) const
        {
            if (!has_printed_)
                throw std::runtime_error("unsupported type");
        }
    };
    
    std::ostream& operator<<(std::ostream& os, const boost::any& v)
    {
        typedef boost::mpl::vector SupportedTypes;
        StreamInserter si(os, v);
        boost::mpl::for_each(si);
        return os;
    }
    
    int main(int, char**)
    {
        std::cout << boost::any(42.0) << std::endl;
        std::cout << boost::any(42) << std::endl;
        std::cout << boost::any(42UL) << std::endl;
        std::cout << boost::any("42") << std::endl;
        std::cout << boost::any(std::string("42")) << std::endl;
        std::cout << boost::any(bool(42)) << std::endl; // throws exception
    }
    

提交回复
热议问题