2016-07-08 3 views
1

В приведенном ниже коде используется вариант повышения std :: map, который содержит пары int/MyVariant. Я могу правильно инициализировать свою карту, где первый элемент содержит пару 33/A, а второй содержит пар 44/B. А и В имеют функцию, что я хотел бы иметь возможность вызывать после получения соответственно их инициализированный элемент карты:Каков правильный синтаксис варианта C++ для вызова функции-члена, заданной для конкретного варианта?

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

Что бы правильный синтаксис, что делать?

+1

вы пробовали 'увеличить :: получить (myAVariant) .Fa()'? –

+1

С точки зрения компилятора с помощью варианта вы удаляете информацию о том, что такое переменная реального типа. C++ по-прежнему является строго типизированным языком, и поэтому информация должна быть в какой-то момент предоставлена ​​обратно ... –

ответ

3

Буст :: вариант способа сделать это с помощью посетителя:

#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

Смежные вопросы