我总是看到std :: forward如下所示,在模板函数中使用
template<class T>
void foo(T&& arg): bar(std::forward<T>(arg)){}
假设我想这样做。
class A
{
private:
std::function<void()> bar;
public:
template<class T>
A(T&& arg):
bar(std::forward<T>(arg))
{}
};
因为bar已经定义了它的类型。我也可以直接将T指定为std::function<void()> >
。
class A
{
private:
std::function<void()> bar;
public:
A(std::function<void()>&& arg):
bar(std::forward<std::function<void()>>(arg))
{}
};
两者都可以编译。但是,第二个实现仅支持A(const std::function<void()>)
。虽然第一个实现支持A(const std::function<void()>&)
和A(std::function<void()>&&)
等
答案 0 :(得分:4)
前进是其论点的有条件的举动。当且仅当传递给它的类型是值类型或右值引用类型时,它几乎等同于std::move
。
移动是对右值参考的强制转换。
如果您将不同的类型传递给std::forward
而不是其参数类型,那么它会做出可怕的事情。如果在两者之间可转换,这通常涉及在函数内创建临时函数,然后返回对它的引用。
传递给std::forward(x)
的正确方法是X
,其中x
的类型为X&&
。任何其他东西都将是非常古怪和高级使用,并可能会导致意外的行为......
在你的情况下,the second works fine,但没有意义。由于std::forward
是条件移动,我们将其传递给固定类型,因此我们知道它是std::move
。
因此,我们应该将std::forward<std::function<void()>>(arg)
替换为std::move(arg)
,这更加清晰,更加传统。此外,在这种情况下也相同。
通常std::forward
只应在您使用转发引用的情况下使用。