2016-12-01 5 views
2

J'essaie d'utiliser boost :: variant en C++ 11 pour créer ceci mais je ne sais pas comment. J'ai donc cette structure des données de classe basés sur des modèles <>Comment faire pour récupérer une valeur boost :: variant pour une classe modèle

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

stockés dans un

std::map<string,dataVar> dataMap

Ce serait génial si je pouvais récupérer le type de données en quelque sorte que je puisse affecter le valeurs mais je n'ai aucune idée de comment faire ce travail avec élégance

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

Ce ne compile pas depuis le tem Les supports de plaque nécessitent un type statique.

J'ai vu d'autres réponses proposant une conception de visiteur mais j'ai aussi besoin du type pour les données <> pour obtenir l'article.

Répondre

4

En supposant que les deux data<A> et data<B> ont la même interface, vous pouvez utiliser un visiteur struct avec un templateoperator():

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


En C++ 14, vous pouvez visiter la variante en place en utilisant un 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


(Si vous êtes intéressé par la visite de la variante en utilisant lambdas et 14 C++ fonctions, j'ai écrit deux articles à ce sujet: part 1 et part 2.)

+2

La solution C++ 14 est suffisamment impressionnante je suggère de l'inclure, même dans une question C++ 11. :) – Yakk

+0

@Yakk: ajouté! :) –