1. 慎重考虑移动操作
有时候移动操作没那么好,例如:
-
对象不支持移动,此时会回退为拷贝
-
移动不会比拷贝快
- 如:小字符串SSO,数据不存储在堆中,移动不一定比拷贝快
-
移动不可用:某些上下文要求移动操作
noexcept
,但该操作没有,可能会被回退为拷贝(取决于库实现)
因此需要多考虑。
2. std::forward
失败的场景
完美转发可能失败:
-
花括号初始化器:模板
T
推导失败- 解决:在外面声明花括号初始化的
std::initializer_list
变量,再调用,此时T
推导为std::initializer_list
- 解决:在外面声明花括号初始化的
-
0
或NULL
作为空指针:推导出整数类型,不能完美转发- 解决:使用
nullptr
- 解决:使用
-
const static
的完美转发:若只有声明,没给出定义,链接可能失败- 解决:需要给出它的定义
-
重载函数或模板的名称:当传入的是一个函数(有重载),或者是一个模板函数,当传入它的名称,编译器不知道传入哪个函数实例,从而转发失败
-
解决:
-
对于函数重载:使用
using
定义函数签名,然后强转函数实例 -
对于模板:特化它
-
-
-
位域:有些编译器支持自定义字段大小,但non-
const
引用不应该绑定到位域,因为它可能不能被寻址(例如取3~5位的数据),C++不能创建一个指向任意bit的指针(只能任意byte)- 解决:将位域字段拷贝出来,再传入函数中