2014-02-28 51 views
2

據我瞭解copy-and-swap成語,它有一個需要bolierplate代碼的缺點。考慮一個簡單的「剛好保持所有這些該死的 - 檸檬」的結構:自定義交換樣板

struct MuchData { 
private: 
    std::string one, two; 
    int three; 
    std::vector<Something> four; 
    MyType five; 
    MyOtherType six, seven; 
    unsigned long long int still_overflows; 

public: 
    MuchData() : one("."), two("/"), three(0), four(), five(), six(-1), seven(0), still_overflows(0) 
    { } 

    MuchData(const MuchData& rhs) : one(rhs.one), two(rhs.two), three(rhs.three), four(rhs.four), five(rhs.five), six(rhs.six), seven(rhs.seven), still_overflows(rhs.still_overflows) 
    { } 

    MuchData(MushData&& old) : one("."), two("/"), three(0), four(), five(), six(-1), seven(0), still_overflows(0) 
    { swap(*this, old); } 

    MuchData& operator=(MuchData old) { swap(*old, this); return *this; } 

    friend void swap(MuchData& left, MushData&right) { 
     using std::swap; 

     swap(left.one, right.one); 
     swap(left.two, right.two); 
     swap(left.three, right.three); 
     swap(left.four, right.four); 
     swap(left.five, right.five); 
     swap(left.six, right.six); 
     swap(left.seven, right.seven); 
     swap(left.still_overflows, right.still_overflows); 
    } 

    // And now we can go and do something interesting 
}; 

寫在

: one(".") 
, two("/") 
, three(0) 
// etc. 

風格的初始化,這段代碼需要更大的空間。並且MyTypeMyOtherType也可能用這種技術來定義......有什麼辦法可以減少這裏的重複性?例如,當添加新字段時,忘記添加相應的swap(...)行會非常容易,這會導致一個神祕的切片。

回答

2

有一兩件事你可以做的是成員存儲在std::tuple,並提供一個名爲訪問器FOT他們,就像這樣:

struct MuchData { 
private: 
    std::tuple<std::string, std::string, int, std::vector<Something>, MyType, MyOtherType, unisgned long long> data; 

    std::string& one() { return std::get<0>(data); } 
    const std::string& one() const { return std::get<0>(data); } 

    //etc. 
}; 

是的,你的交易一塊樣板另一個,但你只會寫一次名字;例如,構造函數的語法將更加簡潔。即使你忘了添加一個訪問器,swap()也可以正常工作(因爲它只是元組的swap())。使用C++ 1y,甚至可以使用auto&const auto&作爲訪問器的返回類型,從而消除更多的重複。

+0

不壞。由於MSVC 2010(我使用)提供了對'std :: tuple'或多或少體面的支持,這就是我會花一段時間的答案。 –

1

您可以使用類初始化,以減少初始化字段的標準值的構造函數之間的重複:

class MuchData { 
    std::string one{"."}; 
    std::string two{"/"}; 
    // ... 

那麼默認的和移動的構造變得微不足道。

MuchData() = default; 

MuchData(MuchData&& o) { swap(*this, o); } 

而且你可以默認拷貝構造函數:

MuchData(const MuchData&) = default; 
+0

很好的答案。不幸的是,我將無法走出MSVC 2010很長一段時間 - 但總有一天這將會被使用。 –