簡體   English   中英

有效創建C ++ 11移動和復制感知結構

[英]Efficiently creating C++11 move and copy aware structs

我試圖將可以利用高效std :: move / copy構造/和賦值操作的高效C ++ 1x結構放在一起。 這些結構分為2個基本類別,即POD結構和非POD結構。 我已經養成了使用樣板代碼編寫這些結構的習慣,但是我很確定編譯器在此方面的工作比我可以做的更好,並且每個類的鍵入都很多。 我的問題是,利用默認的編譯器操作我可以做的最少工作是什么。 例如,我知道,一旦定義了一個顯式構造函數,就會抑制移動和賦值運算符的自動生成。 我也希望沒有超類的非POD結構具有默認的析構函數,從基類繼承的非POD結構具有默認的虛擬析構函數。 如何有效執行這些操作的規則一直令我感到困惑。

PAGE_DATA結構的原始版本如下

using PAGE_DATA = struct page_data {
    std::string name;
    std::vector<SCRN_TEXT> elements;
    std::vector<int> jumpTable;
};

然后,我添加了樣板代碼以使該數據結構移動,並且還添加了一個顯式的構造函數(如果沒有該構造函數,我將不得不使用大括號(不太好讀)用聚合初始化對其進行初始化)。

using PAGE_DATA = struct page_data {
    explicit page_data(const std::string& rName = std::string(), 
        const std::vector<SCRN_TEXT>& rElements = std::vector<SCRN_TEXT>(), 
        const std::vector<int>& rJumpTable = std::vector<int>())
        : name(rName)
        , elements(rElements)
        , jumpTable(rJumpTable)
    {}
    //! Defaulted copy constructor.
    page_data(const page_data&) = default;
    //! Defaulted move constructor.
    page_data(page_data&&) = default;

    //! Non-throwing copy-and-swap idiom unified assignment.
    page_data& operator=(page_data rhs) {
        rhs.swap(*this);
        return *this;
    }

    //! Non-throwing-swap idiom.
    void swap(page_data& rhs) noexcept {
        // enable ADL (not necessary in our case, but good practice)
        using std::swap;
        // swap base members
        // ...
        // swap members here
        swap(name, rhs.name);
        swap(elements, rhs.elements);
        swap(jumpTable, rhs.jumpTable);
    }

    virtual ~page_data() = default;

    std::string name;
    std::vector<SCRN_TEXT> elements;
    std::vector<int> jumpTable;
}; 

被調用的相關簡單POD結構如下所示:

using COLOR_TYPE = enum color_type
{
    BLACK   = 0x0,
    CYAN    = 0x1,
    RED     = 0x2,
    YELLOW  = 0x3,
    GREEN   = 0x4,
    MAGENTA = 0x5,
    AMBER   = 0x6,
    WHITE   = 0x7
};

using SIZE_TYPE = enum size_type {
    SMALL_CHAR = 0x0,
    BIG_CHAR = 0x1
};

using MODIFY_TYPE = enum modify_type {
    NORMAL      = 0x0,
    UNDER       = 0x2,
    FLASH       = 0x4,
    FLASH_UNDER = 0x6
};

using SCREEN_ATTR = struct screen_attr {
    COLOR_TYPE    color  : 4;
    SIZE_TYPE     size   : 2;
    MODIFY_TYPE   blink  : 4;
    unsigned char unused : 6;
};

using CDU_ROWCOL = struct cdu_rowcol {
    int  v;
    int  h;
};

using SCRN_TEXT = struct scrn_text {
    CDU_ROWCOL loc;
    SCREEN_ATTR  attrib;
    std::string text;
};

整理完一個現場coliru演示之后 ,我能夠驗證樣板是否正確。

int main() {
    std::cout << "assertions work fine" << std::endl;
    static_assert(std::is_copy_constructible<PAGE_DATA>(), "not copy constructible");
    static_assert(std::is_move_constructible<PAGE_DATA>(), "not move constructible");
}

您的原始結構已經可以完美移動構建了。 需要時,編譯器已經生成了您編寫的所有其他樣板代碼。

我的問題是,利用默認的編譯器操作我可以做的最少工作是什么。

最小值-相當理想的數量-是您的原始版本,可以充分利用默認操作。

您的page_data::swap可能比通用的std::swap效率更高,並且它不會阻止任何隱式成員函數的生成,因此可能值得保留。但是,如果有的話,它可能僅稍好一點,因此,您可能需要衡量是否值得使類定義混亂。

我喜歡這個回答我的問題 ,“......如果你發現自己寫的移動運營商和移動構造函數,那是因為你還沒有充分分解的問題。”

暫無
暫無

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

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