我读了很多,但还是听不懂。这两个变体之间有什么区别:
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 。很抱歉,这是一个愚蠢的问题,但我确实无法解决。
答案 0 :(得分:4)
如果val_t
不是左值引用类型,则构造函数中的value
是右值引用,而std::forward
等效于std::move
。
如果val_t
是左值引用,则value
也是如此。 std::forward
然后返回一个左值引用,然后代码进行编译。 std::move
返回一个右值引用,该值不能绑定到m_value
(这是一个左值引用),并且编译器报告错误。
fact_t<std::string> f(str);
编译失败的原因是它试图将左值传递给需要右值的参数。