zoukankan      html  css  js  c++  java
  • C++11以上的新特性整理

    1、nullptr

    void foo(char *); 
    void foo(int);
    foo(NULL) //编译出错,不知道调用哪个,可能调用了foo(int)
    foo(nullptr) //ok ,调用foo(char*)
    //用nullptr替换原先的NULL

    2、constexpr

    #define LEN 10
    
    int len_foo() {
        return 5;
    }
    
    int main() {
        char arr_1[10];
        char arr_2[LEN];
        int len = 5;
        char arr_3[len+5];          // 非法
        const int len_2 = 10;
        char arr_4[len_2+5];        // 合法
        char arr_5[len_foo()+5];  // 非法
    
        return 0;
    }
    
    改成:constexpr int len_foo() {
        return 5;
    }
    constexpr int len = 5;
    

     3、auto 与 decltype用于类型推导

    // 由于 cbegin() 将返回 vector<int>::const_iterator 
    // 所以 itr 也应该是 vector<int>::const_iterator 类型
    for(auto itr = vec.cbegin(); itr != vec.cend(); ++itr);

    auto x = 1; auto y = 2; decltype(x+y) z;

    4、基于范围的for循环

    int array[] = {1,2,3,4,5};
    for(auto &x : array) {
        std::cout << x << std::endl;
    }

    5、using的新用法,using可以替换typedef,可读性更好,也更灵活

    template <typename T,typename U,int value>
    class SuckType
    {
    public:
        T a;
        U b;
        SuckType():a(value),b(value){}
    };
    
    template <typename U>
    using NewType = SuckType<int, U, 1>;     //typedef不支持模板推导  
    using Process = int(*)(void*);           // 等效于 typedef int(*Process)(void*);

    6、override,final关键字,override显示表明子类需要重载父类的方法,final说明这个类或者方法不允许重写

    struct Base {
        virtual void foo(int);
    };
    struct SubClass: Base {
        virtual void foo(int) override; // 合法
        virtual void foo(float) override; // 非法, 父类没有此虚函数
    };
    
    struct Base { virtual void foo() final; }; 
    struct SubClass1 final: Base { }; // 合法 
    struct SubClass2 : SubClass1 { }; // 非法, SubClass 已 final 
    struct
    SubClass3: Base { void foo(); // 非法, foo 已 final };

    7、委托构造函数与继承构造

    //委托构造
    class Base {
    public:
        int value1;
        int value2;
        Base(){
            value1 = 1;
        }
        Base(int value) :Base() {
            value2 = value;
        }
        virtual void foo(int) {};
    
    };
    class Sub : public Base
    {
    public:
        using Base::Base;//继承构造
    };

    8、enum增强

    enum class new_enum :unsigned int {
        value1,
        value2,
        value3=100,
        value4,
        value5=100
    };
    
    
    int main(int argc, const char *argv[])
    {
        if (new_enum::value3 == new_enum::value5)
        {
            cout << "equal" << endl;
        }
        if (static_cast<int>(new_enum::value1) == 0)
        {
            cout << "equal" << endl;
        }
        if (new_enum::value2 == 1)   //编译报错
        {
            cout << "equal" << endl;
        }
        if (new_enum::value4==static_cast<new_enum>(1))
        {
            cout << "equal" << endl;
        }
        
    }  

     9、可变参数模板,初始化列表,这个有点复杂,建议再找相关文档学习

    template<class T>
    T sum(T & t)
    {
        return t;
    }
    template<class T,class ... Args>
    T sum(T t, Args... rest)
    {
        return t + sum<T>(rest...);
    }
    
    template<class T=int>
    class FooVector
    {
    public:
        using l = initializer_list<T>;
        std::vector<T> m_ve;
        FooVector(const l &list)
        {
            for (auto &x : list)
            {
                m_ve.push_back(x);
            }
        }
    
        void print()
        {
            for (auto &x : m_ve)
            {
                cout << x << endl;
            }
        }
    };
    
    int main(int argc, const char *argv[])
    {
    sum(1,2,3,6,7); FooVector
    <> a{ 1,2,3,4 }; a.print(); }

     10、lambda表达式

    [...] (...) ... {...}

    [] 内是一个capture,可以在lambda内部访问的"nonstatic外部变量",如果没有要访问的变量,可以为空。static变量是可以直接被访问的。

    () 内是参数,和函数参数一样。

    ... 是mutable, 异常明细, 属性说明符(noexcept等), 或者返回类型。如果其中之一出现,那么必须出现()。

    {} 内是函数体,在这里面写明lambda要完成的工作。

    [](){cout << "hello world"; }();
    
    //[] 空捕获列表
    //[name1, name2, ...] 捕获一系列变量
    //[&] 引用捕获, 让编译器自行推导捕获列表
    //[=] 值捕获, 让编译器执行推导应用列表
    
    int x=10,y=20;
    auto f = [&](int a) -> int { cout << "hello, world " << a <<x<<y++<< endl; return a; }; 
    cout<<y;

    11、std::function与std::bind

    int foo(int a, int b, int c) {
        ;
    }
    int main() {
        // 将参数1,2绑定到函数 foo 上,但是使用 std::placeholders::_1 来对第一个参数进行占位
    std::function<int(int,int,int)> f = foo;
    f(1,2,3);
    auto bindFoo = std::bind(foo, std::placeholders::_1, 1,2); // 这时调用 bindFoo 时,只需要提供第一个参数即可 bindFoo(1); }
  • 相关阅读:
    textarea宽度、高度自动适应处理方法
    Table嵌套去掉子table的外边框
    发现原来自己挺能给自己找理由开脱的
    Life is not the amount of breath you take.
    在遍历ResultSet的循环中再执行SQL会发生什么(前提:同一个Statement)
    按月查询数据
    Oracle SQL 判断某表是否存在
    在Python程序中执行linux命令
    在Oracle中十分钟内创建一张千万级别的表
    Redis Sentinel结构 及相关文档
  • 原文地址:https://www.cnblogs.com/xuhuajie/p/9917175.html
Copyright © 2011-2022 走看看