2012-01-18 37 views
5

我需要找到一个更好的解决方案将数据类型传递到boost::variant这样函数可以优雅地检索存储的变量类型。我已经提出了一个适用于我的实现,但我担心有更好的方法。优雅的方法来传递数据类型为`的boost :: variant`

// file name: p192.cpp 
#include <iostream> 
#include <iomanip> 
#include <string> 
#include <map> 
#include <boost/variant.hpp> 

using namespace std; 

enum TypePassIn 
{ 
    INT_TYPE, 
    DOUBLE_TYPE, 
    STRING_TYPE, 
    PERSON_TYPE, 
    LAST_TYPE = PERSON_TYPE 
}; 

struct Person 
{ 
    Person(int _age, string _name) : age(_age), name(_name) {}  
    int age; 
    string name; 
}; 

void PrintVariant(map<string, boost::variant<int, double, string, Person> > _mapValues, TypePassIn tpi) 
{ 
    switch(tpi) 
    { 
    case INT_TYPE: 
     cout << boost::get<int>(_mapValues["int"]) << endl; 
     break; 
    case DOUBLE_TYPE: 
     cout << setprecision (15) << boost::get<double>(_mapValues["double"]) << endl; 
     break; 
    case STRING_TYPE: 
     cout << boost::get<string>(_mapValues["string"]) << endl; 
     break; 
    case PERSON_TYPE: 
     cout << "Age: " << (boost::get<Person>(_mapValues["Person"])).age; 
     cout << ", Name: " << (boost::get<Person>(_mapValues["Person"])).name << endl; 
     break; 
    default: 
     break; 
    } 
} 

int main(void) 
{ map<string, boost::variant<int, double, string, Person> > mapValues; 

    mapValues["int"] = 10; 
    PrintVariant(mapValues, INT_TYPE); 

    mapValues["double"] = 100.99; 
    PrintVariant(mapValues, DOUBLE_TYPE); 

    mapValues["string"] = "Hello world"; 
    PrintVariant(mapValues, STRING_TYPE); 

    mapValues["Person"] = Person(10, "Tom"); 
    PrintVariant(mapValues, PERSON_TYPE);  
}  

~/Documents/C++/boost $ ./p192 
10 
100.99 
Hello world 
Age: 10, Name: Tom 

正如可以从上面的代码中所见,实施的方法可以处理本地类型和定制的数据类型。在理想情况下,我们可以在不引入enum TypePassIn

回答

7

的情况下执行此操作。您可以使用(静态)visitor pattern,如Boost.Variant教程中所示。

struct VariantPrinter : boost::static_visitor<void> 
{ 
    void operator()(int int_val) 
    { 
     std::cout << int_val << std::endl; 
    } 
    void operator()(double double_val) 
    { 
     std::cout << std::setprecision(15) << double_val << std::endl; 
    } 
    // etc. 
}; 

void PrintVariant(const boost::variant<...>& the_variant) 
{ 
    boost::apply_visitor(VariantPrinter(), the_variant); 
} 

int main() 
{ 
    std::map<std::string, boost::variant<...> > mapValues; 

    mapValues["int"] = 10; 
    PrintVariant(mapValues["int"]); 

}