2016-07-08 1 views
1

Le code ci-dessous utilise une variante boost d'un std :: map qui contient des paires int/MyVariant. Je suis capable d'initialiser correctement ma carte où le premier élément contient la paire 33/A et le second contient la paire 44/B. A et B ont chacun une fonction que je voudrais pouvoir faire appel après avoir récupéré respectivement leur élément de carte initialisés:Quelle est la bonne syntaxe de la variante C++ pour appeler une fonction membre définie sur une variante particulière?

#include "stdafx.h" 
#include "boost/variant/variant.hpp" 
#include "boost/variant/get.hpp" 
#include "boost/variant/apply_visitor.hpp" 
#include <map> 

struct A { void Fa() {} }; 
struct B { void Fb() {} }; 

typedef boost::variant< A, B > MyVariants; 
typedef std::map< const int, MyVariants > MyVariantsMap; 
typedef std::pair< const int, MyVariants > MyVariantsMapPair; 

struct H 
{ 
    H(std::initializer_list<MyVariantsMapPair> initialize_list) : myVariantsMap(initialize_list) {} 

    MyVariantsMap myVariantsMap; 
}; 

int main() 
{ 
    H h { { 33, A {} }, { 44, B { } } }; 

    auto myAVariant = h.myVariantsMap[ 33 ]; 
    auto myBVariant = h.myVariantsMap[ 44 ]; 

    A a; 
    a.Fa(); // ok 

    // but how do I call Fa() using myAVariant? 
    //myAVariant.Fa(); // not the right syntax 

    return 0; 
} 

Quelle serait la syntaxe correcte pour le faire?

+1

Avez-vous essayé 'stimuler :: get (myAVariant) .Fa()'? –

+1

Du point de vue du compilateur en utilisant la variante, vous effacez l'information quel est le type réel de la variable. C++ est toujours un langage fortement typé et en tant que tel l'information devrait être fournie à un certain moment ... –

Répondre

3

La façon boost :: variante de le faire est d'utiliser un visiteur:

#include <boost/variant/variant.hpp> 
#include <map> 
#include <iostream> 
struct A { void Fa() {std::cout << "A" << std::endl;} }; 
struct B { void Fb() {std::cout << "B" << std::endl; } }; 

typedef boost::variant< A, B > MyVariants; 
typedef std::map< const int, MyVariants > MyVariantsMap; 
typedef std::pair< const int, MyVariants > MyVariantsMapPair; 

struct H 
{ 
    H(std::initializer_list<MyVariantsMapPair> initialize_list) : myVariantsMap(initialize_list) {} 

    MyVariantsMap myVariantsMap; 
}; 


class Visitor 
    : public boost::static_visitor<> 
{ 
public: 

    void operator()(A& a) const 
    { 
     a.Fa(); 
    } 

    void operator()(B& b) const 
    { 
     b.Fb(); 
    } 

}; 

int main() 
{ 
    H h { { 33, A {} }, { 44, B { } } }; 

    auto myAVariant = h.myVariantsMap[ 33 ]; 
    auto myBVariant = h.myVariantsMap[ 44 ]; 

    boost::apply_visitor(Visitor(), myAVariant); 
    boost::apply_visitor(Visitor(), myBVariant); 

    return 0; 
} 

live example