代码之家  ›  专栏  ›  技术社区  ›  Denis Steinman

在类的构造函数中前进和移动有什么区别?[副本]

  •  3
  • Denis Steinman  · 技术社区  · 7 年前

    我读了很多关于它的书,但还是没能读到。这两种变体之间有什么区别:

    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);
    

    但它会导致编译时错误。虽然我从其他话题和 参考文献 那个 str 左值 std::forward 允许使用它。我在哪里失踪?

    附笔。 很抱歉,如果这是一个愚蠢的问题,但我真的无法理解。

    1 回复  |  直到 7 年前
        1
  •  4
  •   Igor Tandetnik    7 年前

    如果 val_t 不是左值引用类型,则 value in构造函数是一个右值引用,并且 std::forward 相当于 std::move .

    如果 价值 . 转发 然后返回一个左值引用并编译代码。 移动 返回不能绑定到的右值引用 m_value (这是一个左值引用),编译器报告一个错误。

    Demo

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