C++ 确保调用了move构造函数

C++ 确保调用了move构造函数,c++,c++11,move,move-semantics,C++,C++11,Move,Move Semantics,我有以下简化的代码示例: #include <algorithm> #include <iostream> using namespace std; class ShouldBeMovedWhenSwapped { public: // ShouldBeMovedWhenSwapped() = default; // ShouldBeMovedWhenSwapped(ShouldBeMovedWhenSwapped&&) = default; //

我有以下简化的代码示例:

#include <algorithm>
#include <iostream>

using namespace std;

class ShouldBeMovedWhenSwapped
{
public:
//  ShouldBeMovedWhenSwapped() = default;
//  ShouldBeMovedWhenSwapped(ShouldBeMovedWhenSwapped&&) = default;
//  ShouldBeMovedWhenSwapped(const ShouldBeMovedWhenSwapped&) = default;
//  ShouldBeMovedWhenSwapped& operator=(ShouldBeMovedWhenSwapped&&) = default;

    struct MoveTester
    {
        MoveTester() {}
        MoveTester(const MoveTester&) { cout << "tester copied " << endl; }
        MoveTester(MoveTester&&) { cout << "tester moved " << endl; }
        MoveTester& operator=(MoveTester) { cout << "tester emplaced" << endl; return *this; } // must be declared if move declared
    };

    MoveTester tester;
};

int main()
{
    ShouldBeMovedWhenSwapped a;
    ShouldBeMovedWhenSwapped b;
    std::swap(a,b);
    return 0;
}
#包括
#包括
使用名称空间std;
类应该被移动
{
公众:
//shouldbemovedhenswaped()=默认值;
//shouldbemovedhenswaped(shouldbemovedhenswaped&&)=默认值;
//shouldbemovedhenswaped(const shouldbemovedhenswaped&)=默认值;
//shouldbemovedhenswaped&运算符=(shouldbemovedhenswaped&&)=默认值;
结构移动测试仪
{
MoveTester(){}

MoveTester(const MoveTester&){cout问题的第一部分是一个过时的编译器,但还有一个问题:您以次优的方式声明了
MoveTester::operator=
,它按值获取其参数,因此会额外调用一次copy/move构造函数。请尝试此版本的
MoveTester

struct MoveTester
{
    MoveTester() {}
    MoveTester(const MoveTester&) { cout << "tester copied " << endl; }
    MoveTester(MoveTester&&) { cout << "tester moved " << endl; }
    MoveTester& operator=(const MoveTester&) { cout << "tester copy assignment" << endl; return *this; } // must be declared if move declared
    MoveTester& operator=(MoveTester&&) { cout << "tester move assignment" << endl; return *this; } // must be declared if move declared
};
也许即使使用GCC4.7,您也会得到类似的结果



关于第二个问题,标准保证
std::vector
的move构造函数具有恒定的时间复杂度。问题是编译器是否遵守标准。我相信确保的唯一方法是调试或评测代码。

您使用的编译器是什么?对我来说,您很可能使用的是旧GCC编译器,我猜是4.7版。x@AntonSavin谢谢!这是一个快速的方法,可以看出它取决于编译器。我在问题中添加了信息。至于我的第二个问题?@user1708860:声明移动赋值
T&operator=(T&&&)
将自动生成移动构造函数
T(T&&)
,所以使用了copy。我这样声明是因为“复制和交换习惯用法”,但如果我更改运算符,我确实会得到准确的输出。现在我更困惑了,这似乎是我想要的输出。根据链接问题,这个版本应该会产生最佳代码…@user1708860没有矛盾e、 您的版本确实会使用复制和交换习惯用法,因此在
operator=
中,您只需交换内容,而不需要做太多工作。只需更新编译器,您就可以使用原始版本。@user1708860现在您了解了为什么复制和交换习惯用法在性能方面通常是次优的。它的好处是易于实现,并且d易发生强异常安全。
struct MoveTester
{
    MoveTester() {}
    MoveTester(const MoveTester&) { cout << "tester copied " << endl; }
    MoveTester(MoveTester&&) { cout << "tester moved " << endl; }
    MoveTester& operator=(const MoveTester&) { cout << "tester copy assignment" << endl; return *this; } // must be declared if move declared
    MoveTester& operator=(MoveTester&&) { cout << "tester move assignment" << endl; return *this; } // must be declared if move declared
};
tester moved 
tester move assignment
tester move assignment