auto 函数名 (形参表) ->decltype(表达式)
lambda表达式的名称是一个表达式 (外观类似函数),但本质绝非如此
[捕获表] (参数表) 选项 -> 返回类型 { 函数体; }
// lambda表达式 #include#include using namespace std; int Max(int x, int y){ return x > y ? x : y; } int main( void ){ int a = 10, b = 20; cout << Max(a,b) << endl;; auto f = [](int x, int y)->int{ return x > y ? x : y; }; // 编译器根据lambda表达式(1)生成一个类 (2)类内定义函数操作符函数 (3)返回这个类的匿名对象 /* class Z4mainEUliiE_{ public: int operator()(int x, int y){ return x > y ? x : y; } }; auto f = Z4mainEUliiE_{}; */ cout << "f的类型:" << typeid(f).name() << endl; cout << f(a,b) << endl; // f.operator()(a,b) // lambda表达式可以没有返回值类型,根据return判断 cout << [](int x, int y) { return x+y; }(a,b) << endl; /* class X{ public: auto operator()(int x, int y)->decltype(x+y){ return x + y; } }; cout << X{}(a,b) << endl; // cout << X{}.operator()(a,b) << endl; */ // lambda表达式可以没有返回类型,也没有retrun语句,返回类型为void [](int x, int y){ cout << x << ' ' << y << endl; }(a,b); /* class XX{ public: void operator()(int x, int y){ cout << x << ' ' << y << endl; } }; XX{}(a,b); // XX{}.operator()(a,b) */ // 如果没有形参,可以省略不写 []{ cout << "无聊" << endl;}(); /* class XXXX{ public: void operator(){ cout << "无聊" << endl; } }; XXXX{}(); // XXXX().operator()() */ return 0; }
// lambda表达式 -- 捕获表(捕获lambda表达式外部的变量信息) #include#include using namespace std; int a = 10; class Y{ public: void foo(/* Y* this */ int c = 30 ){ cout << "-------------[]----------------" << endl; [](int d = 40){ cout << "a=" << a << endl; cout << "b=" << b << endl; // cout << "c=" << c << endl; // error cout << "d=" << d << endl; // cout << "e=" << e << endl; // error }(); /* class X{ public: void operator()(int d = 40)){ cout << "a=" << a << endl; cout << "b=" << b << endl; // cout << "c=" << c << endl; // error cout << "d=" << d << endl; // cout << "e=" << this->e << endl; // error } }; X{}(); */ cout << "-------------[c]----------------" << endl; // 捕获外部变量的值 [c](int d = 40){ cout << "c=" << /*++*/c << endl; }(); /* class XX{ public: XX(int m):c(m){} //这里的c并不是foo函数的形参,而是XX类的一个成员变量 void operator()(int d = 40){ cout << "c=" << c << endl; // //这里的c并不是foo函数的形参,而是XX类的一个成员变量 } private: const int c; //这里的c并不是foo函数的形参,而是XX类的一个成员变量 }; XX{c}(); // 这里的c是foo函数的形参c XX(c).operator()() */ cout << "-------------[&c]----------------" << endl; [&c](int d = 40){ cout << "c=" << ++c << endl; }(); cout << "-------------[&c]----------------" << endl; [this](int d = 40){ cout << "e=" << e << endl; }(); } private: static int b; int e; }; int Y::b = 20; int main( void ){ Y y; y.foo(); return 0; }
int a; int& b = a; // OK int c; int& d = a + c; // ERROR
int&& e = a + c;// OK int&& f = a; // ERROR
const int& g = a + c; // OK const int& h = a; // OK
没有必要有常右值引用,因为常右值引用,完全可以被常左值引用替代
// 左值/右值 左值引用/右值引用 #includeusing namespace std; int foo( ) { int m=888; return m; } int main( void ) { // 当前作用域的生命期 // 具名内存-->能够取址-->左值|非常左值(无const修饰) // |常左值 (有const修饰) int a = 10; int& ra = a; // ok const int& cra = a; // ok const int b = 10; // int& rb = b; // error const int& crb = b; // ok // 语句级生命期(引用可以延长右值的生命期) // 匿名内存-->不能取址-->右值|直接更改右值毫无意义(98/03标准给出结论) // | 11标准认为给了真名就可以改 const int& ri = 10; int&& rri = 10; const int& rf = /*|888|*/foo( ); // (1)分配一块内存空间 (2)生成跳转指令 int&& rrf = foo(); return 0; }
//左值引用/右值引用 #includeusing namespace std; int main( void ) { int a,c; // 左值引用只能引用左值,不能引用右值 int& b = a; // ok // int& d = a + c; // error // 右值引用只能引用右值,不能引用左值 int&& e = a + c; // ok e = 666; // ok 通过右值引用不会丧失修改目标内存的权限 // int&& f = a; // error // 常左值引用(万能引用),既能引用左值,也能引用右值 const int& g = a; // ok const int& h = a + c; // ok // g = 666; // error 但是通过常左值引用会丧失修改目标内存的权限 return 0; }
资源的转移 代替 资源的重建
保证功能正确的情况下,做到性能提升