variant和any有些类似,是一种可变类型,是对C/C++中union概念的增强和扩展;
普通的union只能持有普通数据类型,而不能持有string、vector等复杂类型,而variant则可以;
variant接口和any类似,但它是一个模板类;
variant的默认构造函数通过模板中的第一个类型(严格地说,为bounded type)进行构造;
如果模板中的第一个类型不存在默认构造,将会报错,哪怕后续类型存在默认构造;
第一个模板类型不存在默认的构造函数,variant对象可直接通过模板中的任意类型的构造函数的方式得以构造;
一个variant对象也可通过模板中的任意类型的构造函数进行赋值;
有两种方式获取 variant对象中的内容: apply_visitor,安全且强大; get<T>,十分方便
get<T>方法存在一个显著的缺陷,如果一个函数接受variant<int, string>,我们无法知道传递进来的variant对象,是int类型还是string类型;
在实际应用中,对variant类型对象内容的获取需要一个比get方法更为鲁棒的获取机制,这正是安全且强大的apply_visitor;
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
/* boost_variant.cpp
variant和any有些类似,是一种可变类型,是对C/C++中union概念的增强和扩展; 普通的union只能持有普通数据类型,而不能持有string、vector等复杂类型,而variant则可以; variant接口和any类似,但它是一个模板类; variant的默认构造函数通过模板中的第一个类型(严格地说,为bounded type)进行构造; 如果模板中的第一个类型不存在默认构造,将会报错,哪怕后续类型存在默认构造; 第一个模板类型不存在默认的构造函数,variant对象可直接通过模板中的任意类型的构造函数的方式得以构造; 一个variant对象也可通过模板中的任意类型的构造函数进行赋值; 有两种方式获取 variant对象中的内容: apply_visitor,安全且强大; get<T>,十分方便 get<T>方法存在一个显著的缺陷,如果一个函数接受variant<int, string>,我们无法知道传递进来的variant对象,是int类型还是string类型; 在实际应用中,对variant类型对象内容的获取需要一个比get方法更为鲁棒的获取机制,这正是安全且强大的apply_visitor; */ #include <iostream> #include <string> #include <vector> #include <algorithm> #include <boost/variant.hpp> using namespace boost; using namespace std; class var_visitor : public static_visitor<void> { public: template<typename T> void operator()(T& i) const { cout << i << endl; } }; int main(void) { //union union { int i; int d; } u; u.d = 3.14; u.i = 3; // overwrites u.d union { int i; //string s; // illegal: string is not a POD type! }uu; //variant variant<int, string> v; // 初始状态下,v被初始化为int(0) cout << v.type().name() << endl; // int cout << v << endl; // 0 class A { public: A(int){} }; //variant<A, int> va; // 第一个参数A不存在默认构造,报错! variant<A, int> va1 = 23; variant<A, int> va2 = A(23); variant<int, string> vis; vis = "Michael"; //获取值 string& str = boost::get<string>(vis); str += " Joessy! "; cout << str << endl; variant<int, string> vvv; vvv = "Hello world"; apply_visitor(var_visitor(), vvv); cin.get(); return 0; } |
参考: