class的构造函数中的forward和move有什么区别?

时间:2018-12-13 01:31:12

标签: c++ c++11

我读了很多,但还是听不懂。这两个变体之间有什么区别:

template <typename val_t>
class fact_t: public exp_t<val_t> {
    val_t m_value;
public:
    fact_t(val_t &&value) : m_value{std::forward<val_t>(value)} {}
};

template <typename val_t>
class fact_t: public exp_t<val_t> {
    val_t m_value;
public:
    fact_t(val_t &&value) : m_value{std::move(value)} {}
};

有人可以举一个例子,说明一个变体将失败而另一个变体仍然可以工作吗?

我尝试以另一种方式使用第一个变体:

std::string str = "str";
fact_t<std::string> f(str);

但是会导致编译时间错误。尽管从其他主题和 cppreference 可以理解,str左值,而std::forward允许使用它。我在哪里失踪?

PS 。很抱歉,这是一个愚蠢的问题,但我确实无法解决。

1 个答案:

答案 0 :(得分:4)

如果val_t不是左值引用类型,则构造函数中的value是右值引用,而std::forward等效于std::move

如果val_t是左值引用,则value也是如此。 std::forward然后返回一个左值引用,然后代码进行编译。 std::move返回一个右值引用,该值不能绑定到m_value(这是一个左值引用),并且编译器报告错误。

Demo

fact_t<std::string> f(str);编译失败的原因是它试图将左值传递给需要右值的参数。