2016-12-01 55 views
2

我想在C++ 11中使用boost :: variant来创建这个,但我不知道如何。 所以我存储在模板类数据<>如何检索一个模板类的boost :: variant值

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

的这种结构的

std::map<string,dataVar> dataMap

这将是巨大的,如果我能检索数据类型莫名其妙,所以我可以分配值,但我不知道如何使这项工作优雅

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

这不会自编程序,板托架需要静态类型。

我看过其他回复提出的访问者设计,但我也需要数据类型<>才能获得该项目。

回答

4

假设都data<A>data<B>具有相同的接口,你可以使用访问者structtemplateoperator()

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


在C++ 14中,您可以通过使用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


(如果您是使用lambda表达式和C++ 14的功能感兴趣的变种探视,我已经写了两篇文章吧:part 1part 2

+2

C++ 14解决方案更加棒,我会建议包括它,即使在C++ 11问题中也是如此。 :) – Yakk

+0

@Yakk:加入! :) –