2

I am trying to use the boost::variant in c++11 to create this but I m not sure how. So I have this structure of the templated class data<>

typedef boost::variant< data<A>,data<B>> dataVar;

stored in a

std::map<string,dataVar> dataMap

It would be great if I could retrieve the type for data somehow so I can assign the values but I have no idea how to make this work elegantly

void registerDataFor(string str)
  {
     auto itr = dataMap.find(str);

    if(itr == dataMap.end())
        return;

     dataVar = itr->second;
     data<v.which()> itemData= boost::get<v.which()>(v);
     someArray.push_back(itemData.getIntegerValue());
     registerDataFor(itemData.getString());
  }

This doesn't compile since the template brackets require a static type.

I ve seen other responses proposing a visitor design but I also need the type for data<> to get the item.

T.Zak
  • 309
  • 2
  • 14

1 Answers1

4

Assuming that both data<A> and data<B> have the same interface, you can use a visitor struct with a template operator():

struct registerImpl : boost::static_visitor<void>
{
    template <typename T>
    void operator()(T& x) const
    {
        someArray.push_back(x.getIntegerValue());
        registerDataFor(x.getString());   
    }
};

void registerDataFor(std::string str)
{
    auto itr = dataMap.find(str);

    if(itr == dataMap.end())
        return;

    registerImpl visitor;
    boost::apply_visitor(visitor, itr->second);
}

wandbox example


In C++14, you can visit the variant in place by using a generic lambda.

void registerDataFor(std::string str)
{
    auto itr = dataMap.find(str);

    if(itr == dataMap.end())
        return;

    boost::apply_visitor([](auto& x){
        someArray.push_back(x.getIntegerValue());
        registerDataFor(x.getString());      
    }, itr->second);
}

wandbox example


(If you are interested in variant visitation using lambdas and C++14 features, I've written two articles about it: part 1 and part 2.)

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416