一、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); }