【问题标题】:"Defaulted" move constructor and assignment - weird behaviour“默认”移动构造函数和赋值 - 奇怪的行为
【发布时间】:2015-11-25 15:08:07
【问题描述】:

所以我有一个简单的类的例子,它有两个成员变量。我已经声明了一个副本和一个移动构造函数,它们是= default,这将强制编译器为我生成它们。现在我的问题是这个。当使用移动构造函数(或赋值)时,为什么我移动的对象保持不变?

例如,如果我有:

myclass obj(4, 5);
myclass obj2 = std::move(4, 5);

据我了解,在第二行 obj 之后将包含“nothing”,因为它将被移动到 obj2 中,其值为 (4, 5)。我知道我不习惯在这里更正术语....

完整代码:

#include <iostream>
#include <utility>

template<class T1, class T2>
class Pair
{
public:
    T1 first;
    T2 second;

public:
    //CONSTRUCTORS
    constexpr Pair() = default;

    constexpr Pair(const T1& _first, const T2& _second)
        : first(_first), second(_second)
    {}

    constexpr Pair(T1&& _first, T2&& _second)
        : first(std::forward<T1>(_first)), second(std::forward<T2>(_second))
    {}

    constexpr Pair(const Pair&) = default;
    constexpr Pair(Pair&&)      = default;

    //ASSIGNMENT
    Pair &operator=(const Pair&) = default;
    Pair &operator=(Pair&&)      = default;
};

int main()
{
    Pair<int, int> p(1, 2);

    Pair<int, int> p2 = p; //all good, p = {1, 2} and p2 = {1, 2}

    Pair<int, int> p3 = std::move(p); //p = {1, 2} and p3 = {1, 2}
                                    //why isn't p "moved" into p3??
                                    //p should be empty??

    //same thing occurs with the move assignment. why?

    std::cout << p.first << " " << p.second << "\n";
    std::cout << p2.first << " " << p2.second << "\n";
    std::cout << p3.first << " " << p3.second << "\n";
}

现场示例:http://coliru.stacked-crooked.com/a/82d85da23eb44e66

【问题讨论】:

  • 它如何包含“无”?你如何让int 商店“无”?您可以复制它然后将其设置为0,但这将比复制它更多工作,并且移动意味着至少与复制一样有效,所以如果编译器会很愚蠢通过做额外的工作来“移动”简单的值。

标签: c++ c++11 move move-semantics


【解决方案1】:

int 的默认移动只是一个副本。

【讨论】:

  • 我认为所有构建类型都一样,不是吗?
  • 哦,我不知道。所以如果我做 Pair<:string std::string> p("1", "2");它会按我的预期工作吗?修辞问题。已经测试过了。
【解决方案2】:

默认的移动构造函数和移动赋值将简单地调用std::move 给所有成员。就像副本一样,默认的副本构造函数简单调用所有成员的副本。

您的代码是正确的,调用std::move后,移动的数据仍然存在是正常的。为什么?因为原语上的std::move 复制了它们。编译器不会生成将 int 移动到0 的代码,因此它是一个简单的副本。但是,如果您配对包含更复杂的类型,例如 std::vector&lt;int&gt;,则移动的向量实际上会以空的形式结束。

【讨论】:

  • vector 移出的对象处于有效但未指定的状态。它不一定是空的。
猜你喜欢
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-05
相关资源
最近更新 更多