c++11 - 转发转发引用的单个成员

标签 c++11 move-semantics class-members forwarding-reference

我有一个函数可能会 move 一个通用参数,但通过它们的成员。以下哪个选项更正确:

  • 这看起来更自然,但很奇怪,因为参数可能被 move 了两次 [a],这很奇怪,因为对象可能变得无效。
    template<class T> 
    void fun(T&& t){
        myhead_ = std::forward<T>(t).head_;
        myrest_ = std::forward<T>(t).rest_;
    }
    
  • 这不可能是不正确的,但它可能不会 move 任何东西。
    template<class T> void fun(T&& t){
        myhead_ = std::forward<decltype(t.head_)>(t.head_);
        myrest_ = std::forward<decltype(t.rest_)>(t.rest_);
    }
    
  • 这似乎是正确的,但代码太多。
    template<class T> void fun(T& t){
        myhead_ = t.head_;
        myrest_ = t.rest_;
    }
    template<class T> void fun(T&& t){
        myhead_ = std::move(t.head_);
        myrest_ = std::move(t.rest_);
    }
    


  • [a] 正如@Angew 指出的那样,此语句是不正确的,它看起来只是 move 了两次。 std::forward (如 std::move )实际上并没有 move 任何东西。最多 move 成员(通过后续操作 decltype(myhead)::operator= 但这正是目标。)

    最佳答案

    您的第一个代码非常好:

    template<class T> 
    void fun(T&& t){
        myhead_ = std::forward<T>(t).head_;
        myrest_ = std::forward<T>(t).rest_;
    }
    

    那是因为标准保证在做 a.b 时和 a是一个 xvalue(例如一个转发的右值引用),a.b 的结果也是一个外值(即可以从中 move )。另请注意 std::forwardstd::move不要自己做任何实际的 move ,它们只是类型转换。所以从 t 搬家没有风险。在您的代码中两次。

    关于c++11 - 转发转发引用的单个成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50149972/

    相关文章:

    c++ - 无法使用成员函数更改私有(private)变量

    c# - 我怎样才能不笨拙地/乏味地阻止将空字符串写入类(class)成员的尝试?

    c++ - 如果显式定义了构造函数,是否必须初始化类成员?

    c++ - 成员初始化列表中的 unique_ptr

    c++ - 以后可以使用分配器构造 std::tuple 的元素吗?

    c++ - std::list.size() 如何具有恒定的复杂性?

    c++ - 为什么我不能在 C++14 的 lambda 中 move std::unique_ptr?

    c++ - unordered_map 的存在决定了是使用复制构造函数还是 move 构造函数

    pointers - 当 Vec 被 move 时,我可以(不安全地)持有一个指向 Vec 元素的指针吗?

    java - java中向成员变量传递值