Немного поздно для этой вечеринки, но любой, кого это может заинтересовать, может также использовать std::tuple
и std::for_each
-подобный шаблон, который перебирает кортеж.
Это основано на ответе ingomueller.net в этой теме.
У меня был недавний случай, когда я создал карту свойств (считывая значения конфигурации, в основном, фундаментальные типы, из файла XML и вставляя их в std::unordered_map
, где тип значениятипа any
. В целях отладки я хотел иметь возможность распечатать всю карту с ее ключами и значениями вместе с типом значения.
В этом проекте я не использую Boost вообще, я использовал свою собственную any
реализацию, но она очень похожа на boost :: any.
Оператор вставки в основном выглядит следующим образом:
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;
}
шаблон for_eachвыглядит следующим образом (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>{});
}
При этом просто используйте класс StreamInserter
или что-то подобное, показанное в ответе Ingos.
Надеюсь, это поможет.