Un poco tarde para este partido, pero cualquier persona que pueda estar interesada también puede utilizar std::tuple
y una plantilla std::for_each
-como que itera sobre una tupla.
Esto se basa en la respuesta de ingomueller.net en este hilo.
Tuve un caso reciente donde creé un mapa de propiedades (leyendo valores de configuración, principalmente tipos fundamentales, de un archivo XML e insertándolos en un std::unordered_map
, donde el tipo de valor es del tipo any
. Para la depuración quería ser capaz de imprimir el mapa entero con sus claves y valores junto con el tipo del valor.
en ese proyecto no estoy utilizando Boost en absoluto, he usado mi propia any
aplicación, pero es muy similar al impulso :: cualquiera.
El operador de inserción básicamente se ve así:
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;
}
La plantilla for_each se parece a esto (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>{});
}
Con esto sólo tiene que utilizar la clase StreamInserter
o algo similar se muestra en la respuesta Ingos.
Espero que esto ayude.
¿No puedes usar 'boost :: variant'? Ese sería el método más fácil: algo como 'any' solo parece simple al principio. –
Bueno, algún código externo ha producido este mapa para mí. Tal vez puedo convertirlo a 'map' de alguna manera? –
Frank
Creo que viene de Boost.PO? ¿Tienes control sobre la fuente usando Boost.PO? –