boost的variant库类似于联合体,但是联合体中只能接受POD类型,但variant中并无此限制,它可以接受任意的类型.
 
boost::variant <int, std::string , double> u;
u = 4;
int i = boost:: get<int >(u);
std::cout << "int : " << i << std ::endl;
 
u = "hello world!" ;
std::string s = boost::get <std:: string>(u );
std::cout << "string : " << s << std ::endl;
 
u = 1.2;
double d = boost:: get<double >(u);
std::cout << "double : " << d << std ::endl;
 
输出:
int : 4
string : hello world!
double : 1.2
 
要获取variant中的值时,一定要知道当前类型,并由get操作进行获取相应的值,如果转型失败,会抛出bad_get异常,get操作时运行时检测,我们可以通过检测get返回值来进行判断转型是否成功如下:
 
void printer (boost:: variant<int , std:: string, double >& u)
{
    if (int *pi = boost::get <int>(& u))
    {
        std::cout << "int : " << * pi << std ::endl;
    }
    else if (std:: string *ps = boost:: get<std ::string>(& u))
    {
        std::cout << "string : " << * ps << std ::endl;
    }
    else if (double * pd = boost ::get< double>(&u ))
    {
        std::cout << "double : " << * pd << std ::endl;
    }
}
 
通过printer函数中我们为get传进去的是variant的地址,返回如果是NULL的话则转型失败,进行下一个转型操作,依次来判断数据类型.可以看到通过get操作不仅需要知道需要转型的类型,而且还要在运行时判断转型是否成功,boost提供了编译时类型检测的安全访问方式,通过apply_visitor进行访问.
 
class printer_visitor : public boost::static_visitor <void>
{
public:
    void operator ()(int i) const
    {
        std::cout << "int : " << i << std ::endl;
    }
 
    void operator ()(std:: string& s ) const
    {
        std::cout << "string : " << s << std ::endl;
    }
 
    void operator ()(double d) const
    {
        std::cout << "double : " << d << std ::endl;
    }
};
int main ()
{
    boost::variant <int, std::string , double> u;
    printer_visitor visitor ;
    u = 4;
    boost::apply_visitor (visitor, u);
    u = "hello world!" ;
    boost::apply_visitor (visitor, u);
    u = 1.2;
    boost::apply_visitor (visitor, u);
}
 
我们定义一个variant时,如果我们没有给它赋任何值时,是不是他就是空呢?boost文档中"Never-Empty" Guarantee.也就是即使我们没有初始化,他也不会是空,默认的类型是我们模板参数的第一个,上例中默认的类型也就是int,值是0.
 
我们还可以将variant作为容器的元素例如:
 
std::vector <boost:: variant<int , std:: string, double > > v;
v.push_back (4);
v.push_back ("hello world!");
v.push_back (1.2);
std::for_each (v. begin(), v .end(), boost::apply_visitor (printer_visitor()));

boost总结之variant的更多相关文章

  1. 实现一个 Variant

    很多时候我们希望能够用一个变量来保存和操作不同类型的数据(比如解析文本创建 AST 时保存不同类型的结点),这种需求可以通过继承来满足,但继承意味着得使用指针或引用,除了麻烦和可能引起的效率问题,该做 ...

  2. 64位win7下安装Boost 1.59.0 + boost.python 1.59.0 + gccxml + pygccxml + pyplusplus(py++)

    由于安装过程中实在是出现了N多问题,所以不得不专门写个帖子来记录一下这破东西在Win7下的安装过程,避免以后还要再用的时候踩坑. 1.Boost简介 Boost库是一个可移植.提供源代码的C++库,作 ...

  3. (原创)用c++11打造好用的variant

    variant类似于union,它能代表定义的多种类型,允许将不同类型的值赋给它.它的具体类型是在初始化赋值时确定.boost中的variant的基本用法: typedef variant<in ...

  4. 转:MFC之COleVariant

    COleVariant 本质上是一个枚举,用同一种类型来表达不同的子类型.如同boost中的variant. 例子 COleVariant var(3.6f); float v = var.fltVa ...

  5. Boost--variant (C++中的union)

    union联合体类型的问题 只能用于内部类型,这使得union在C++中几乎没有用 所以boost提供了variant,相当于是C++中的union #include "boost/vari ...

  6. COleVariant类

    COleVariant本质上是一个枚举,用同一种类型来表达不同的子类型.如同boost中的variant. COLeVariant类是对VARIANT结构的封装. VARIANT结构包含两部分.其一是 ...

  7. boost::tie()和boost::variant()解说

    #include<iostream> #include<boost/tuple/tuple.hpp> #include<boost/variant.hpp> #in ...

  8. 让boost.variant支持lambda表达式访问

    前言 之前写个过一篇博客叫<浅谈boost.variant的几种访问方式>,里面讲到了可以通过访问者方式来获取variant的值,但是在重载函数operator()里面只能够获取varia ...

  9. 浅谈boost.variant的几种访问方式

    前言 variant类型在C++14并没有加入,在cppreference网站上可以看到该类型将会在C++17加入,若想在不支持C++17的编译器上使用variant类型,我们可以通过boost的va ...

随机推荐

  1. 小shell函数

     whoport() {  port=$1  echo "------ who occupied port: $port ----------"  info=$(sudo lsof ...

  2. 鸟哥私房菜笔记:Iptables:数据包过滤软件

    数据包进入流程:规则顺序的重要性 iptables利用的是数据包过滤机制,所以它会分析数据包的包头数据.根据包头数据与定义的规则来决定该数据包是否可以进入主机或者是被丢弃.也就是说,根据数据包的分析资 ...

  3. asp.net发送E-mail

    发送电子邮件也是项目开发当中经常用到的功能,这里我整理了一个发送电子邮件(带附件,支持多用户发送,主送.抄送)的类库,供大家参考. 先上两个实体类,用于封装成Mail对象. /// <summa ...

  4. 制作UI纹理(UI Texture)

    什么情况下使用UI Texture UI Texture的功能是在屏幕上显示一张图片,在这一点上它和Sprite有着相似的功能,但是UI Texture会消耗单独的DrawCall去渲染,并会单独加载 ...

  5. sqlserver 2008express版本启用混合登陆和sa

    本机环境:win10 64位  vs2010及其自带的数据库 sqlserver2008 express版本 用命令行登陆数据库: osql -E -Slocalhost\sqlexpress 登陆成 ...

  6. delphi xe5 android sample 中的 SimpleList 是怎样绑定的

    C:\Users\Public\Documents\RAD Studio\12.0\Samples\FireMonkeyMobile 例子中的绑定方式如下图: 1.拖拽一个listview到界面上,然 ...

  7. 防止横竖屏时,iphone自动缩放的一段js代码

    function orientation_change() {     var viewport = document.querySelector('meta[name="viewport& ...

  8. [BZOJ 4033] [HAOI2015] T1 【树形DP】

    题目链接:BZOJ - 4033 题目分析 使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值. 这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Fat ...

  9. Ubuntu下将Sublime Text设置为默认编辑器

    转自将Sublime Text 2设置为默认编辑器 修改defaults.list 编辑/etc/gnome/default.list文件,将其中的所有gedit.desktop替换为sublime_ ...

  10. DataTable转换List<T>集合的方法

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data; ...