关于新的 C++ 转发引用的讨论太多了。 然而,有时在特定情况下,我仍然不清楚它们是否提供任何优势。
很明显,按值传递重状态仿函数(就像随机数生成器一样)不是一个好主意。所以让我们使用引用。好吧,但是……
...使用转发引用有什么好处吗
template <class T, class Functor>
T func(T x, Functor &&f)
{
T y;
// do some computations involving f(x) and store it in y
return y;
}
而不是常量引用
template <class T, class Functor>
T func(T x, const Functor &f)
{
T y;
// do some computations involving f(x) and store it in y
return y;
}
在接受仿函数对象而不转发它们的函数中?
问题的主要方面是性能方面的考虑。
最佳答案
选择取决于f
的作用、接受右值是否有意义、函数对象是否预期较小以及引用语义是否有意义。大多数标准库算法按值获取函数对象,因为它们预计几乎没有状态,按值获取可以更有效。
采用转发引用的一个很好的例子是std::shuffle
:
template< class RandomIt, class URNG >
void shuffle( RandomIt first, RandomIt last, URNG&& g );
URNG 必须作为引用,因为 1) 它不需要可复制和 2) 你真的不想复制它(既因为 RNG 的复制成本非常高,也因为用户通常想要 shuffle
以更改 RNG 的状态;如果使用相同的 RNG 对象两次调用 shuffle
导致相同的“随机”顺序,他们会感到非常惊讶)。您也不能通过 const 引用获取它,因为那样您就不能对其调用 operator()
- 生成随机数会改变 RNG 的状态。
然后在非常量左值引用 URNG&
和转发引用 URNG&&
之间进行选择。因为有时你确实想接受一个右值 URNG——例如当你想洗牌到相同的可重现顺序时,所以你在调用点创建一个带有固定种子的生成器——the latter was chosen .
关于c++ - 将引用转发为仿函数参数的优点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32596441/