可以std :: forward将std :: function <void()>作为类类型吗?

时间:2016-06-02 19:11:00

标签: c++11

我总是看到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()>&&)

1 个答案:

答案 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只应在您使用转发引用的情况下使用。