43 votes

Variante Boost : comment obtenir le type actuellement détenu ?

D'après ce que j'ai compris, tous les types de boost.variant sont analysés en types réels (c'est-à-dire comme si boost variant<int, string> a; a="bla-bla" se transformait après la compilation en string a; a="bla-bla" ) Et donc je me demande : comment obtenir quel type était mettre en variante boost ?

Qu'ai-je essayé :

 #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;
}

18voto

KennyTM Points 232647

boost.variant a une fonction .type() qui peut renvoyer le typeid du type actif, à condition que vous ayez activé RTTI.

Vous pouvez également définir un visiteur statique pour effectuer des actions en fonction du type de contenu de la variante, par exemple

 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;

11voto

richardr Points 731

Vous pouvez utiliser les éléments suivants qui génèrent tous deux des objets std::type_info :

  • la fonction membre type() de boost::variant,
  • l'opérateur C++ typeid() qui peut être appliqué à n'importe quel type ou expression typée,

avec la fonction membre std::type_info::operator==, pour vérifier quel type le boost::variant stocke actuellement. Par exemple,

 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);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X