C++ 何时使用常量引用而不是转发引用
C++ When to use const Reference over Forwarding Reference
考虑我们需要实现一个带有模板化参数T t
的函数f
。该函数不应该复制t
并接受rvalues
和lvalues
,因此可以有两种实现:
template <class T>
void f(const T& t) { ... }
template <class T>
void f(T&& t) { ... }
如果我们想在f
内部更改t
或需要保留值类别,我们必须使用第二个版本。那么按照这种思路,我们何时以及为什么要选择第一种选择?
当您想向函数的客户端提供强有力的保证时,您将主要选择第一个选项,即t
不会在f
内部更改。虽然你可以删除const
限定符,但仍然不能修改t
,如果你不改变参数在函数中引用的值,它被认为是一个const
参数的良好做法和良好的接口设计,而且它可以帮助编译器更好地优化代码。
另外,如果你真的必须的话,要知道你可以使用const_cast
来破解const
的类型安全性,但请记住,你正在这样做:摆脱类型安全。不惜一切代价避免这种情况。
最后,const
限定符不会阻止复制,您可以轻松地执行以下操作:
int main()
{
const int a = 3;
int b = a; // a is copied to b
}
在此通用方案中,没有理由同时写入两个重载。
如果f
只观察其参数,则只需要const T&
重载。
如果f
只是将其参数转发给其他函数,则只需要T&&
重载,并将使用std::forward<T>
。(这包括函数需要保留值的副本的情况,即将其转发给复制/移动构造函数。
相关文章:
- 正在折叠转发引用
- 如何在模板中转发右值和左值引用
- 通过基类接受方法转发派生 UniquePtr 的右值会移动引用而不是复制
- C++ 何时使用常量引用而不是转发引用
- 为什么转发声明的好友类不能在类中引用?
- C++完美转发:如何避免悬空引用
- C++:通用(转发)引用中不允许常量
- 模板模板参数和转发引用
- 常量转发引用给出错误 C2440:"正在初始化":无法从"常量标准::字符串"转换为"常量标准::字符串 &&"
- 具有右值引用,而不是使用可变参数模板转发引用
- 自定义类型转换运算符在转发引用上调用时不起作用(当对象按值传递时有效)
- 如何从常量引用或通过转发模板临时构造对象
- 结构化绑定和转发引用是否混合良好?
- 如何声明接受转发引用并返回引用或副本的函数模板
- 间接转发引用
- 为什么调用转发引用构造函数而不是复制构造函数?
- 为什么 std::get 没有一个接受转发引用的签名
- 有没有办法在不引用其模板类型的情况下转发声明指向类的指针
- c++重新评估引用转发性能
- 右值引用转发错误