簡體   English   中英

確保調用move構造函數

[英]Making sure move constructor gets called

我有以下簡化的代碼示例:

#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;
}

我正在使用MinGW,同時運行'gcc --version'我得到gcc 4.7.2

編輯 :對於第一個問題,請參閱問題中的注釋。 它似乎是gcc中的錯誤。

代碼的輸出取決於注釋了哪些構造函數。 但是我不明白為什么會出現差異。 每個輸出背后的原因是什么?

// Everything commented out
tester moved 
tester copied <---- why not moved?
tester emplaced
tester copied <---- why not moved?
tester emplaced

// Nothing commented out
tester moved
tester moved
tester emplaced
tester moved
tester emplaced

// Move constructor commented out
tester copied
tester moved
tester emplaced
tester moved
tester emplaced

對於我的第二個問題(這就是為什么我開始進行此測試的原因)-假設我有一個帶有大向量的真實案例,而不是類MoveTester, 我如何確定在這種情況下向量是移動的而不是被復制了?

問題的第一部分是一個過時的編譯器,但還有一個過時的編譯器:您MoveTester::operator=優的方式聲明了MoveTester::operator= -它按值接受參數,因此復制/移動構造函數需要額外調用一次。 試試這個版本的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
};

我得到以下輸出

tester moved 
tester move assignment
tester move assignment

即使使用GCC 4.7,也許您也會得到類似的東西。


關於第二個問題, std::vector保證了std::vector的move構造函數具有恆定的時間復雜度。 問題是編譯器是否遵守標准。 我相信唯一可以確保調試或分析代碼的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM