zoukankan      html  css  js  c++  java
  • boost-数据类型之auto、any、tuple、variant

    1、auto、decltype

      auto是C++11中的关键字,它可以通过类型推导自动得到变量或对象的类型,需要注意的是auto会忽略引用,因为引用其实就代表原对象:

    #include <vector>
    #include "boost/assign.hpp"
    using namespace boost::assign;
    
    int main()
    {
        auto i = 10;
        auto f = 12.34;
        auto s = string("abc");
        cout << i << ", " << f << ", " << s << endl;
        int num = i;
        double d = f;
        string str = s;
    
        vector<int> vc = list_of(1) (2) (3);
        auto iter = vc.begin();
        auto iterEnd = vc.end();
        for (; iter != iterEnd; iter++)
        {
            cout << *iter << endl;
        }
    
        return 0;
    }
    View Code

      auto还可以配合C++11中的“尾置返回”,尾置返回”适用于返回类型比较复杂的函数。如以下func函数的返回类型为指向包含三个int元素的数组的地址:

    auto func()->int(*)[3]
    {
        static int ary[3];
        return &ary;
    }
    View Code

      以上代码其实与下面代码效果相同:

    typedef int(*pAry)[3];
    pAry func2()
    {
        static int ary[3];
        return &ary;
    }
    View Code

      auto还可以用在for循环中使代码简单:

        int ary[] = { 1, 2, 3 };
        for (auto e : ary)
        {
            std::cout << e << std::endl;
        }
    
        int ary[] = { 1, 2, 3 };
        for (auto& e : ary)
        {
            e = 0;
        }
        
        char* ary[] = { "c++", "java", "python" };
        for (auto* p : ary)
        {
            std::cout << p << std::endl;
        }
    View Code

     如果我们希望从表达式中推断出要定义变量的类型,但却不想用表达式的值去初始化变量,那么可以使用decltype,需要注意的是如果decltype使用的变量加上一个括号的话那么decltype会返回对应的引用类型:

        int func(int i)
        {
            return i;
        }
        decltype(func(0)) num = 100; //num是int类型,不会调用func()
        
        std::vector<int> vc = { 1, 2, 3, 4, 5 };
        auto size = vc.size();
        for (decltype(size) i = 0; i < size; i++) // i是size_t类型
        {
            ;
        }
    
        int i = 100;
        decltype((i)) d = num; //d是int引用类型,其指向num
    View Code

    2、any

      any功能与auto类似,二者不同之处在于:auto是一个类似int、double、string的C++关键字,它不是一个类,所以没有成员函数可调用,直接把他当做int、double、string这种关键字来使用。any是一个类,只能通过any_cast<>获得any的实际内部值,而不能像auto定义的对象那样直接使用它。

      any也可以用来存储任意类型元素,如int、double、string、vector或自定义类型。它能够存储任意类型的原因是其构造函数和赋值函数opeartor=是模板函数,可以接收任意类型。any不是一个模板类,所以定义元素的时候不必使用<>,如any a = 10;
      需要注意的有两点:
      在any存储字符串的时候只能使用string,如any a = string("hello");,不能使用C风格的字符串,如:any a = "hello";
      如果保存动态内存指针类型,会引起内存泄露,解决方法是使用智能指针shared_ptr来指向动态内存,如:shared_ptr<char> ptrSmart(new char[10]); any a = ptrSmart; 

      any的出现让C++仿佛变成了一种弱类型的动态语言。
      动态语言:运行期间才做数据类型检查的语言,即编译的时候不知道每一个变量的类型,如php、Ruby
      静态语言:编译期间做数据类型检查的语言,即编译的时候就知道每一个变量的类型,如C/C++、C#、JAVA
      强类型:变量一定是有类型的, 且变量/对象的类型一旦确定, 其类型不再允许更改,如C/C++/Java/C#
      弱类型: 变量的类型概念很弱或者没有类型的概念, 不同变量的类型可以更改. 如php、Ruby
      类型安全:的代码不会试图访问自己没被授权的内存区域,如C/C++就不是类型安全的,两个不同类型的指针之间可以通过dynamic_cast进行转换。

      any::empty()判断any是否为空
      any::type()获得内部对象的类型,是一个标准type_info类的引用

      any_cast<>()获得any内部对象值或内部对象指针或内部对象的引用

    #include <vector>
    #include "boost/any.hpp"
    #include "boost/assign.hpp"
    using namespace boost::assign;
    
    
    template <typename T> 
    bool match_type(boost::any& a)
    {
        if (a.empty())
            return false;
    
        return typeid(T) == a.type();
    }
    
    template<typename T> 
    T get_value(boost::any& a)
    {
        BOOST_ASSERT(match_type<T>(a));
    
        return boost::any_cast<T>(a);
    }
    
    template <typename T> 
    T* get_pointer(boost::any& a)
    {
        BOOST_ASSERT(match_type<T>(a));
    
        return boost::any_cast<T>(&a);
    }
    
    template <typename T> 
    T& get_reference(boost::any& a)
    {
        BOOST_ASSERT(match_type<T>(a));
    
        return boost::any_cast<T&>(a);
    }
    
    int main()
    {
        boost::any a = 10;
    
        int iNum = get_value<int>(a);//获得a的内部元素
        cout << iNum << endl;
    
        int * p = get_pointer<int>(a);//获得a内部元素的指针
        cout << *p << endl;
    
        get_reference<int>(a) = 5;//获得a内部元素引用,引用可以被当做左值来使用
        cout << *p << endl;
    
        if (match_type<int>(a))//判断a内部元素类型是否为int
            cout << "true" << endl;
    
        return 0;
    }
    View Code

    3、tuple

      tuple类型类似于std::pair,pair只支持包含两种类型的元素,tuple可以支持包含多个不同类型的元素,比如将其用于多个返回值的函数的话比使用struct更方便,一个简单的使用示例如下:

    #include <cstdio>
    #include <string>
    using std::string;
    #include "boost/tuple/tuple.hpp"
    
    boost::tuple<int, double, string> func()
    {
        int i = 1;
        double d = 5.0;
        string s("hello");
        boost::tuple<int, double, string> tupleCombin(i, d, s);
    
        return tupleCombin;
    }
    
    int main()
    {
        boost::tuple<int, double, string> tupleCombin = func();
        int i = tupleCombin.get<0>();
        double d = tupleCombin.get<1>();
        string s = boost::get<2>(tupleCombin);
    
        return getchar();
    }
    View Code

      c++中现已支持tuple:
     

        std::tuple<int, bool, std::string> item = {99, true, "test"};
    
        int n = std::get<0>(item); // 99
        bool b = std::get<1>(item); // true
        std::get<2>(item) = "hello";
        std::string s = std::get<2>(item); // "hello" 
    View Code

    4、variant

      variant是一种增强的union,C/C++中union只能持有POD(普通数据类型),而不能持有如string、vector等复杂类型,boost的variant则没有这个限制。

  • 相关阅读:
    如何用nginx将vue部署到本地
    数组中引用类型的去重
    关于element 上传文件el-upload
    ----vue3.0 如何拿到 有ref属性的元素;
    关于 el-form rules校验
    x-www-form-urlencoded 传参
    哈哈 v-model 传递参数给子组件
    记 el-tabs el-tab-pane 中嵌套 router-view出现的问题
    nginx跨域
    css3---flex三剑客
  • 原文地址:https://www.cnblogs.com/milanleon/p/5892420.html
Copyright © 2011-2022 走看看