2016-12-01 52 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:加入! :) –