zoukankan      html  css  js  c++  java
  • boost总结之variant

    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()));
  • 相关阅读:
    P2639 [USACO09OCT]Bessie的体重问题Bessie's We…
    P2871 [USACO07DEC]手链Charm Bracelet
    P1983 车站分级
    P1038 神经网络
    P1991 无线通讯网
    P1546 最短网络 Agri-Net
    P1197 [JSOI2008]星球大战
    P1004 方格取数
    P1111 修复公路
    pd_ds 之 hash
  • 原文地址:https://www.cnblogs.com/ourroad/p/3362077.html
Copyright © 2011-2022 走看看