- lambdas:inline函数,一种类型
auto I=[]{ cout<<"Hello World"<<endl; }; I();//小括号调用
[...外部的变量](...参数)#mutable throwSpec -> retType#{...} #号内可写可不写,如果有一个写了就必须写前面的小括号
int id=0; auto f=[id]()mutable{ cout<<id<endl; ++id; }; id=42; f(); f(); f(); cout<<id<<endl; 打印结果: 0 1 2 42 //侧面说明lambda有状态,一直是同一个类对象,与函数指针不同 相当于不知名的函数对象(或者仿函数): class Functor { private: int id; public: void operator()(){ cout<<id<<endl; ++id; } }; Functor f;
int id=0; auto f=[&id]()mutable{ cout<<id<endl; ++id; }; id=42; f(); f(); f(); cout<<id<<endl; 打印结果: 42 43 44 45
lambda没有默认构造函数和赋值函数int id=0; auto f=[&id](){ cout<<id<<endl; ++id; }; id=42; f(); f(); f(); cout<<id<<endl; 报错:【error】没有mutable不能修改id
所以在set用lambda的时候要写上参数auto cmp=[](Person a,Person b){ return a.height>b.height; }; set<Person ,decltype(cmp)>coll(cmp);
template<class Key,class Compare=less<Key>,class Alloc=alloc> class set{ private: rep_type t; public: set():t(Compare()){}; explicit set(const Compare& comp):t(comp()){}; }
- decltype
2.1 返回类型template< typename T1,typename T2> decltype(x+y) add(T1 x,T2 y); //主要为了让编译器通过,但是这样写编不过,因为编译器还没看到x,y template< typename T1,typename T2> auto add(T1 x,T2 y) -> decltype(x+y);
- variadic template
void print() { } template<typename T,typename... Types> void print(const T& firstArg,const Types& ... args) { cout<<firstArg<<endl; print(args...); }
- initializer list
initialzer_list<>, {}大括号内个数不定,类型需要一致,后面是个arrayint i; //未定义 int j{}; //j=0,大括号赋初值 int* p; // 未定义 int* q{}; //q=nullptr //{}设初值不能窄化 int a{5.0}; //error or warning
- 如果一个class有move版本的构造或者赋值函数,要把它们写成不抛出异常 ,noexcept
- 类的后面有final(),表示不可被继承,如果虚函数后有final(),表示虚函数不可被复写
- 模板的模板参数
template<typename T,template<class T> class Container> class XCLs { private: Container<T> c; XCLs(){ for(long i=0;i<SIZE;++i) { c.insert(c.end(),T()); } Container<T> c1(c); Container<T> c2(std::move(c)); c1.swap(c2); } } template<typename T> using Vec=vector<T,allocator<T>>; XCLs<MyString,Vec> c1;
- 临时对象是一个右值
move(左值)会变成一个右值 - tuple
tuple<int, double, string> s( 1, 3.0, "spf" ); auto t = make_tuple(1, 2.0, "spf" ); int main() { cout << get<0>(s) << " " << get<1>(s) << " " << get<2>(s) << endl; int i=0; double d=0; string m; tie(i, d, m) = s; //将i,d,m赋值为s的对应值 cout << i << " " << d << " " << m; system("pause"); return 0; }
- 右值在传递过程中会产生不完美传递
int a=0; process(a); //视为process(int& ):0,左值处理 process(1); //视为process(int&& ):1,右值处理 process(move(a)); 视为process(int&& ):0,强制将a改为右值处理 forward(2); //forward(int&& ):0process(int &):0,右值经过forward()传给另一个函数变成了左值; void process(int& i) { cout<<"lvalue"<<i<<endl; } void process(int&& i) { cout<<"rvalue"<<i<<endl; } void forward(int&& i) { cout<<"forward(int&&)"<<i<<endl; process(i); }
以上内容参考侯捷老师的C++标准 11-14 总结