类型推断
template<typename T>
void f(ParamType param);
f(expr); // 使用expr调用f
ParamType是指针*或引用&
忽略expr的修饰&后决定类型
template<typename T>
void f(T ¶m); // param是一个引用
int x = 27;
const int cx = x;
const int &rx = cx;
f(x); // T是int,param是int&
f(cx); // T是const int,param是const int&
f(rx); // T是const int,param是const int&
ParamType是通用引用&&
忽略expr的修饰&后决定类型type
- 若expr是左值,T和param都变成左值引用type&
- 若expr是右值,T是type,param是右值引用type&&
template<typename T>
void f(T &¶m); // param是一个通用引用
int x = 27;
const int cx = x;
const int &rx = cx;
f(x); // T是int&,param是int&
f(cx); // T是const int&,param是const int&
f(rx); // T是const int&,param是const int&
f(27); // T是int,param是int&&
ParamType传值方式
忽略expr的修饰const、voliate、&后决定类型
template<typename T>
void f(T param); // param是传值方式
int x = 27;
const int cx = x;
const int &rx = cx;
f(x); // T和param都是int
f(cx); // T和param都是int
f(rx); // T和param都是int
通用引用被左值初始化为左值引用,被右值初始化为右值引用。只有模板参数为精确的T&&形式(没有const等修饰符),且T需要被推断,才为通用引用。否则,为右值引用。
对函数参数param,右值引用使用std::move(param)转换,通用引用使用std::forward<T>(param)转换
类型推断会折叠引用的引用:有左值引用就是左值引用,都右值引用就是右值引用
闭包
[=]传值调用只会捕获局部变量和this指针,不会捕获成员变量和static变量。static变量只能传引用到闭包。
最好使用初始化捕获列表。
对闭包的auto&&通用引用使用decltype()转发参数:std::forward<decltype(param)>(param)
条件变量
虚假唤醒:超时醒来,或被唤醒后检查条件为假(比如刚有的队列元素被其它线程抢走),需要对条件进行再判断以避免虚假唤醒 https://www.cnblogs.com/tqyysm/articles/9765667.html
volatile
C++的volatile没有并发特性,用在特殊内存(如内存映射),告诉编译器不要对这块内存执行任何优化。比如把x=10; x=20;优化成x=20;,把auto y=x;y=x;优化成y=x;,这种消除冗余对普通内存可行,对映射内存不可行,因为每个语句都是与外设的通信。
参考
- Effective Modern C++, Scott Meyers