C++11更新内容(2)--完美转发--默认移动构造/移动赋值--1116
1.完美轉發
1.1萬能引用
void Fun(int &x){ cout << "左值引用" << endl; } void Fun(const int &x){ cout << "const 左值引用" << endl; }void Fun(int &&x){ cout << "右值引用" << endl; } void Fun(const int &&x){ cout << "const 右值引用" << endl; } template<typename T> void PerfectForward(T&& t) {Fun(t); }模板中的&&不代表右值引用,而是萬能引用,其既能接收左值又能接收右值。 模板的萬能引用只是提供了能夠接收同時接收左值引用和右值引用的能力。但是引用類型的唯一作用就是限制了接收的類型,后續使用中都退化成了左值。
如果希望能夠在傳遞過程中保持它的左值或者右值的屬性, 就需要用完美轉發。
1.2 std::forward
template<typename T> void PerfectForward(T&& t) {Fun(std::forward<T>(t)); }?
?2. 新的類功能
2.1 新的默認生成函數
原來C++類中,有6個默認成員函數:
1. 構造函數 2. 析構函數 3. 拷貝構造函數 4. 拷貝賦值重載 5. 取地址重載 6. const 取地址重載
2.1.1 新增1:默認的移動構造函數
如果沒有實現移動構造函數,而且沒實現 析構函數&&拷貝構造函數&&拷貝賦值重載
編譯器會自動生成一個默認的移動構造函數。該構造函數對于內置類型成員進行逐字節拷貝,對于自定義類型,需要看其是否實現了移動構造函數。實現了就用其的移動構造函數,沒實現就用拷貝構造函數。
?2.1.2 新增2:默認的移動賦值重載函數
如果沒有實現移動賦值重載函數,而且沒有實現 析構函數&&拷貝構造函數&&拷貝賦值重載
編譯器胡自動生成一個默認的移動賦值重載函數。對于內置類型逐字節拷貝。對于自定義類型,如果其實現了移動賦值重載,就調用。如有沒有實現,就調用其拷貝構造函數。
例如
class Person { public:Person(const char* name = "", int age = 0):_name(name), _age(age){} private:chy::string _name;int _age; }; int main() {Person s1;Person s2 = s1;Person s3 = std::move(s1);Person s4;s4 = std::move(s2);return 0; }該類沒有實現 析構、拷貝構造、拷貝賦值重載。且成員變量有自定義類型,即是上篇博客展示的非庫中的string(主要是在 移動拷貝、移動賦值重載中添加了打印)
2.2 新增關鍵字
?2.2.1強制生成默認函數的關鍵字default
使用default關鍵字指定生成某默認函數
Person(Person&& p) = default;
Person(const Person& p)=default;
?2.2.2禁止生成默認函數的關鍵字delete
該語法指示編譯器不生成對應函數的默認版本
Person(Person&& p) = delete;
Person(const Person& p)=delete;
2.2.3 final
聲明該類是不能被繼承的類,如果仍然被繼承,編譯時自動報錯。
class A final { public:A(){}protected:int _a; };class B : public A {};2.2.4 override
檢查派生類虛函數是否重寫了基類某個虛函數,如果沒有重寫編譯報錯。
class Car{ public:virtual void Drive(){} }; class Benz :public Car { public:virtual void Drive() override {cout << "Benz-舒適" << endl;} };3.可變參數模板
3.1參數包的使用
?Args是一個模板參數包,args是一個函數形參參數包
?聲明一個參數包Args...args,這個參數包中可以包含0到任意個模板參數。
?3.1.1 遞歸函數方式展開參數包
template <class T, class ...Args> void ShowList2(T value, Args... args) {cout << value << " ";ShowList2(args...); }相當于每次都用剩余的參數列表去調用該函數。參數列表的一個,當做value。
因為是遞歸,所以需要終止條件。
// 遞歸終止函數 template <class T> void ShowList2(const T& t) {cout << t << endl; }? 3.1.2 逗號表達式展開參數包
template <class T> void PrintArg(T t) {cout << t << " "; } //展開函數 template <class ...Args> void ShowList(Args... args) {int arr[] = { (PrintArg(args), 0)... };cout << endl; } int main() {ShowList(1);ShowList(1, 'A');ShowList(1, 'A', std::string("sort"));return 0; }?3.2 empalce
template<class...Args>
void emplace_back (Args&&... args);
void emplace_test() {list<Date> lt1;//這里演示的需要 之前實現的幾個類 這里不貼出來了//我們這里的list在拷貝構造和 構造中分別添加了一句打印lt1.push_back(Date(2022,11,16));lt1.emplace_back(2022,11,16); }?
?發現在list中 使用emplace_back可以少調用一次拷貝構造。
3.3 lambda
想要對一個數據集合中的元素進行排序,可以使用sort方法
sort(array, array+sizeof(array)/sizeof(array[0]));
如果需要從大到小排序
sort(array, array + sizeof(array) / sizeof(array[0]), greater()); //仿函數
bool cmp(int& a1, int& a2){ return a1>a2;}
sort(array, array + sizeof(array) / sizeof(array[0]), cmp);//這里是自己寫的比較函數
?如果需要排序的是自定義類型,需要我們去實現對應的仿函數。
int main() {vector<Goods> v = { { "蘋果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠蘿", 1.5, 4 } };sort(v.begin(), v.end(), ComparePriceLess());//這里都是仿函數sort(v.begin(), v.end(), ComparePriceGreater());//仿函數return 0; }由于每次寫仿函數都需要創建一個結構體/類,在C++11語法中出現了Lambda表達式。
3.3.1 Lambda表達式
lambda表達式書寫格式:[捕捉列表] (參數列表) mutable? -> 返回值類型 { 比較的方法 }
int main() {// 兩個數相加的lambdaauto add1 = [](int a, int b)->int{return a + b; };cout << add1(1, 2) << endl;// 省略返回值auto add2 = [](int a, int b){return a + b; };cout << add2(1, 2) << endl;// 交換變量的lambdaint x = 0, y = 1;auto swap1 = [](int& x1, int& x2)->void{int tmp = x1; x1 = x2; x2 = tmp; };swap1(x, y);cout << x << ":" << y << endl;auto swap2 = [](int& x1, int& x2){int tmp = x1;x1 = x2;x2 = tmp;};swap2(x, y);cout << x << ":" << y << endl;// 不傳參數交換x y的lambda -- 捕捉列表// 默認捕捉的對象不能修改/*auto swap3 = [x, y]()mutable{int tmp = x;x = y;y = tmp;};swap3();cout << x << ":" << y << endl;*/auto swap3 = [&x, &y]{int tmp = x;x = y;y = tmp;};swap3();cout << x << ":" << y << endl;return 0; }總結
以上是生活随笔為你收集整理的C++11更新内容(2)--完美转发--默认移动构造/移动赋值--1116的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2013江苏计算机二级vfp试题,200
- 下一篇: java-net-php-python-