C++11以上的新特性整理

一、nullptride

void foo(char *); 
void foo(int);
foo(NULL) //編譯出錯,不知道調用哪一個,可能調用了foo(int)
foo(nullptr) //ok ,調用foo(char*)
//用nullptr替換原先的NULL

二、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;

 三、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;

四、基於範圍的for循環ui

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

五、using的新用法,using能夠替換typedef,可讀性更好,也更靈活spa

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*);

六、override,final關鍵字,override顯示代表子類須要重載父類的方法,final說明這個類或者方法不容許重寫rest

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 };

七、委託構造函數與繼承構造code

//委託構造
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;//繼承構造
};

八、enum加強blog

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;
    }
    
}  

 九、可變參數模板,初始化列表,這個有點複雜,建議再找相關文檔學習繼承

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(); }

 十、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;

十一、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); }
相關文章
相關標籤/搜索