不需要std::forward
的情况是什么?它用于包装内部函数参数,它是templated-rvalue(也就是说,它可以是lvalue或named-rvalue)。喜欢在:
template<class T>
void outer(T&& t) {
inner(std::forward<T>(t));
}
我猜测一个案例是当内部函数参数按值传递时。还有其他情况吗?当我写std::begin(std::forward<Ct>(ct))
时,我有这个问题,其中Ct是模板化的rvalue-ref。
编辑
如果我没记错的话,这是第三次尝试将这个4岁的问题关闭,因为一些新手不理解这个问题。
“使用前锋的优势?”和“何时不使用带有r值的std :: forward?”是非常不同的问题。首先介绍初学者的r值,然后讨论高级C ++用户的完美转发。我是meta-template library和lambda库的作者,他不需要详细描述基础知识。答案中的信息与其他问题有很大不同。
答案 0 :(得分:6)
当模板参数类型包含值类别时,可以进行完美转发。 (如果这句话没有意义,请花一点时间到familiarize yourself with the problem at hand。)
假设:
template <typename T>
void foo(T&& x);
在foo
的正文中,T
将采用U
或U&
的形式。前者意味着我们通过了右值,后者意味着我们通过了左值。我们可以像这样转发这个事实:
template <typename T>
void foo(T&& x)
{
bar(std::forward<T>(x));
}
将左值传递给foo
,bar
获得相同的左值。将右值传递给foo
,bar
获得右值。
如果无法区分值类别,则转发无用。只有当您使用与上述相同的方式推导出模板参数时,它才有用。是的,它在这里没用:
template <typename T>
void foo(const T& x)
{
// if this was called as foo(1), we're none the wiser
}
答案 1 :(得分:2)
我正在回答我自己的问题,因为到目前为止我没有得到满意的答复。 如果我能得到甚至很小的改进/补充 - 我会选择你接受的答案。
一般来说,如果实现完美转发的效果,std::forward
对内部功能有益。否则它是多余的。
仅当以下任何一项为真时,才使用std::forward
包装内部函数arg:
答案 2 :(得分:-1)
使用std :: forward(在形式参数上对模板化函数,其类型为T&amp;&amp;,T形式的模板的类型参数):
基本原理是,当一个对象可能通过rvalue引用作为参数传递时(这是你允许使用std :: forward),它的信息内容可能会被破坏。因此,当您确定不再使用该信息内容时,您只想这样做。
示例:
#include <utility>
template <class T> void f(T &&t);
template <class T> void g(const T &t);
template <class T>
void outer(bool f_first, T &&t)
{
if (f_first)
{
f(t);
g(t);
}
else
{
g(t);
f(std::forward<T>(t));
}
}
#include <string>
void foo(std::string s)
{
outer(true, s);
outer(true, s + "x");
outer(false, s);
outer(false, std::move(s));
}