2012-01-18 19 views
5

Tôi cần tìm giải pháp tốt hơn để chuyển loại dữ liệu thành boost::variant để chức năng có thể truy xuất kiểu biến dạng được lưu trữ một cách thanh lịch. Tôi đã đưa ra một thực hiện mà làm việc cho tôi nhưng tôi quan tâm có một cách tốt hơn ra khỏi đó.phương thức thanh lịch để chuyển kiểu dữ liệu cho `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 

Như bạn có thể thấy từ mã trên, phương pháp triển khai có thể xử lý cả kiểu gốc và loại dữ liệu tùy chỉnh. Trong trường hợp lý tưởng, chúng tôi có thể làm điều đó mà không cần giới thiệu enum TypePassIn

Trả lời

7

Bạn có thể sử dụng (tĩnh) visitor pattern, như được hiển thị trong hướng dẫn của 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"]); 

} 
Các vấn đề liên quan