How to print boost::any to a stream?

前端 未结 9 1294
悲哀的现实
悲哀的现实 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 07:58

    A little late for this party, but anyone that may be interested can also use std::tuple and a std::for_each-like template that iterates over a tuple.

    This is based on the answer from ingomueller.net in this thread.

    I had a recent case where I created a property map (reading configuration values, mainly fundamental types, from an XML file and inserting them into an std::unordered_map, where the value type is of type any. For debugging purposes I wanted to be able to print the entire map with its keys and values along with the type of the value.

    In that project I am not using Boost at all, I used my own any implementation, but its very similar to boost::any.

    The insertion operator basically looks like this:

    template 
    inline std::basic_ostream&
    operator<< (std::basic_ostream& os, const sl::common::any& v)
    {
        // Types that we support with sl::common::any.
        std::tuple<
            float, double, bool, 
            int8_t, uint8_t, 
            int16_t, uint16_t,
            int32_t, uint32_t, 
            int64_t, uint64_t,
            std::wstring, const wchar_t*,
            StreamInserter::UnsupportedType> t;
    
        // Prepare ostream for printing a value of type any
        StreamInserter si(os, v);
    
        // Iterate over all types in tuple t. If the last type(UnsupportedType) is
        // reached, given v is unsupported.
        for_each(t, si);
        return os;
    }
    

    The for_each template looks like this (C++14):

    template 
    constexpr void for_each_impl(Tuple&& tuple, F&& f, std::index_sequence) {
        using swallow = int[];
        (void)swallow{1,
            (f(std::get(std::forward(tuple))), void(), int{})...
        };
    }
    
    template 
    constexpr void for_each(Tuple&& tuple, F&& f) {
        constexpr std::size_t N = std::tuple_size>::value;
        for_each_impl(std::forward(tuple), std::forward(f),
                      std::make_index_sequence{});
    }
    

    With this just use the StreamInserter class or something similar shown in Ingos answer.

    Hope this helps.

提交回复
热议问题