C++ 何时使用常量引用而不是转发引用

C++ When to use const Reference over Forwarding Reference

本文关键字:引用 转发 C++ 常量 何时使      更新时间:2023-10-16

考虑我们需要实现一个带有模板化参数T t的函数f。该函数不应该复制t并接受rvalueslvalues,因此可以有两种实现:

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>。(这包括函数需要保留值的副本的情况,将其转发给复制/移动构造函数。