c++ boost boost-variant

c++ - Variante Boost: ¿cómo obtener el tipo actual?



boost-variant (3)

Como entendí, todos los tipos de boost.variant se boost.variant en tipos reales (es decir, si boost variant<int, string> a; a="bla-bla" después de la compilación se convierte en string a; a="bla-bla" ) Y entonces me pregunto: ¿cómo obtener qué tipo se puso en impulsar la variante?

¿Qué he intentado?

#include <boost/variant.hpp> #include <boost/function.hpp> #include <boost/shared_ptr.hpp> #include <iostream> int main() { typedef boost::function<double (double x)> func0; typedef boost::function<double (double x, double y)> func1; typedef boost::variant<int, func0, func1> variant_func; func1 fn = std::plus<double>(); variant_func v(fn); std::cout << boost::get<func1>(v)(1.0, 1.0) << std::endl; // this works //std::cout << boost::get<v::type>(v)(1.0, 1.0) << std::endl; // this does not compile with many errors // std::cout << (v)(1.0, 1.0) << std::endl; // this fails with Error 1 error C2064: term does not evaluate to a function taking 2 arguments std::cin.get(); return 0; }


Puede usar lo siguiente para que ambos resulten en objetos std :: type_info:

  • la función de miembro type () de boost :: variant,
  • el operador de C ++ typeid () que se puede aplicar a cualquier tipo o expresión escrita,

junto con la función de miembro std :: type_info :: operator ==, para verificar qué tipo está actualizando el boost :: variant. Por ejemplo,

boost::variant<int, bool, std::string> container; container = "Hello world"; if (container.type() == typeid(std::string)) { std::cout << "Found a string: " << boost::get<std::string>(container); } else if (container.type() == typeid(int)) { std::cout << "Found an int: " << boost::get<int>(container); }


boost.variant tiene una función boost.variant .type() que puede devolver el typeid del tipo activo, siempre que haya habilitado RTTI.

También puede definir un visitante estático para realizar acciones dependiendo del tipo de contenido de la variante, por ejemplo

struct SomeVisitor : public boost::static_visitor<double> { double operator()(const func0& f0) const { return f0(1.0); } double operator()(const func1& f1) const { return f1(1.0, 1.0); } double operator()(int integer) const { return integer; } }; ... std::cout << boost::apply_visitor(SomeVisitor(), v) << std::endl;


v.which() devolverá el índice basado en 0 del tipo del objeto que se mantiene actualmente.

Cuando está recuperando el objeto, su código debe usar un tipo estático (para satisfacer la plantilla de función get<T> ) para referirse a un objeto (efectivamente) tipado dinámicamente.

Necesita probar el tipo (usando which() o type() ) y bifurcar de acuerdo o usar un visitante estático. No importa de qué forma elija, debe indicar explícitamente el tipo estático que desea recuperar y debe coincidir con el tipo dinámico o se lanzará una excepción.

Una forma de evitar este problema es utilizar un tipo de variante directamente, usar una clase que contenga un tipo de variante internamente y luego definir los operadores de conversión implícitos necesarios para usar el objeto con el mínimo esfuerzo.

Tengo un proyecto llamado Dynamic C ++ que usa esta técnica.