zoukankan      html  css  js  c++  java
  • [C/C++] C++2.0新特性学习

    一、判断编译器是否支持

    编译器支持的C++版本,我们只需要打印__cplusplus常量就可以知晓:

    cout<<__cpluscplus<<endl;

    如果打印2011**则是C++11版本,打印2014**就是C++14版本,打印1997**则是C++1.0版本。
    如果使用新版本的IDE,打印发现是1997**,则说明IDE要开启C++2.0的支持,需要进行配置,可以google以下如果配置即可。

    二、Variadic Templates(不定数量模板参数)

    1.使用不定数量模板参数简单例子

    在之前的C++版本中,使用模板可以实现对任意类型数据参数的传递。在2.0版本中,我们可以传入不定数量的模板参数:

    #include <iostream>
    #include <bitset>
    
    using namespace std;
    
    // 3.必须定义一个无参数的空print函数来处理递归最后args中参数为0个的情况
    void print(){}
    
    // 1.从第二个参数开始,可以传入任意个数的参数,而且类型是任意的。注意'...'的位置
    template<typename T, typename... Types>
    // 2.这个函数完成了一个递归的操作,每次将args参数包中的第一个分离出来,剩下的再次递归
    // 但是这里要非常注意,当args中的参数为0个时,则会调用上面的print()无参数版,所以这个无参数版的print()一定要定义,否则编译出错
    void print(const T &firstArg, const Types &... args) {
        cout << firstArg << endl;
        print(args...);
    }
    
    int main() {
        // 第一个参数是float,后面的不定数量参数分别是字符串,bitset以及整数。
        print(7.5, "Hello", bitset<16>(377), 42);
        return 0;
    }    

    这里最需要注意的就是"..."的位置,以及最后递归收敛时的无参数print()函数。

    2.使用不定模板参数例子二

    实现一个简单的tuple类。用于同时保存不同类型、不同数量的数据。

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    template<typename... Values>
    class MyTuple;
    
    template<>
    class MyTuple<> {
    };
    
    // 定义一个模板,包含一个类型Head和一包类型Tail
    template<typename Head, typename... Tail>
    // 定义一个类,继承于比他自己少第一个参数的父类
    class MyTuple<Head, Tail...> : private MyTuple<Tail...> {
        // 将父类定义别名为inherited
        typedef MyTuple<Tail...> inherited;
    public:
        MyTuple() {}
    
        // 构造函数,v赋值给m_head,vtail传递给父类构造函数
        MyTuple(Head v, Tail... vtail) : m_head(v), inherited(vtail...) {}
    
        // 获取当前m_head
        Head head() { return m_head; }
    
        // return后,转型为父类类型,这样再次获取head(),就可以获取到下一个m_head
        inherited &tail() { return *this; }
    
    protected:
        // 第一个元素
        Head m_head;
    };
    
    
    int main() {
        MyTuple<int, float, long, string> t(41, 6.3, 50000, "Good");
        cout << t.head() << endl;  // 打印41
        cout << t.tail().head() << endl;  // 打印6.3
        cout << t.tail().tail().head() << endl;  // 打印50000
        cout << t.tail().tail().tail().head() << endl;  // 打印Good
        return 0;
    }

    三、nullptr

    在2.0版本以前,表示空指针可以使用0和NULL:

    // 以前使用的两种初始化指针为空的方式
    void * ptr = NULL;
    void * ptr = 0;

    在2.0中,空指针有一个特殊的值来代替,就是nullptr:

    void * ptr1 = NULL;
    void * ptr2 = 0;
    void * ptr3 = nullptr;  // C++2.0的新关键字

    另外还有一个nullptr_t是nullptr的类型,即decltype(nullptr),值是void *。

    这样就可以通过这个初始化的值来区分需要调用的函数,例如:

    void * func(int);
    void *func(void *);
    func(0);  // 调用func(int)
    func(NULL);  // 调用func(int)
    func(nullptr);  // 调用func(void *)

    四、auto关键字

    auto关键字是C++2.0的新的关键字,用来自动推导变量的类型。

    例如:

    auto i = 43; // i是int
    double f();
    auto d = f(); // d是double类型,自动从f()的返回值推导

    推导比较长的类型(偷懒):

    vector<string> v;
    auto pos = v.begin();  // pos的类型为vector<string>::iterator

    推导很难的类型:

    auto lf = [](int x)->bool{  ...  };  // lf的类型时lambda函数

     

  • 相关阅读:
    使用基于关系的选择器和伪类选择器创建纯CSS无JavaScript的鼠标移动到上面即可显示的下拉菜单
    git学习教程
    笔记
    luogu P1429 平面最近点对(加强版)
    可持久化数据结构
    luogu P4137 Rmq Problem / mex
    置换群(Burnside引理+Polya定理)
    luogu P1053 篝火晚会
    luogu P3238 [HNOI2014]道路堵塞
    luogu P3812 【模板】线性基
  • 原文地址:https://www.cnblogs.com/leokale-zz/p/12505358.html
Copyright © 2011-2022 走看看