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 <typename TChar>
inline std::basic_ostream<TChar>&
operator<< (std::basic_ostream<TChar>& 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 <typename Tuple, typename F, std::size_t ...Indices>
constexpr void for_each_impl(Tuple&& tuple, F&& f, std::index_sequence<Indices...>) {
using swallow = int[];
(void)swallow{1,
(f(std::get<Indices>(std::forward<Tuple>(tuple))), void(), int{})...
};
}
template <typename Tuple, typename F>
constexpr void for_each(Tuple&& tuple, F&& f) {
constexpr std::size_t N = std::tuple_size<std::remove_reference_t<Tuple>>::value;
for_each_impl(std::forward<Tuple>(tuple), std::forward<F>(f),
std::make_index_sequence<N>{});
}
With this just use the StreamInserter
class or something similar shown in Ingos answer.
Hope this helps.