2013-12-23 27 views
1

這是將所有構造函數轉發給成員數據結構的好方法嗎?將構造函數轉發給成員對象

template<typename VectorData> 
class VectorFunctionality 
{ 
    VectorData data; 
public: 
    VectorFunctionality() = default; 
    VectorFunctionality(const VectorFunctionality&) = default; 
    template<typename ...Args> 
    VectorFunctionality(Args... args) : data(std::forward<Args>(args)...) {}; 
}; 

VectorData可以是std ::陣列,標準::矢量等 VectorFunctionality繼承所有VectorData c'tors的。 這有助於避免在VectorFunctionality中寫入許多c'tors,其他的爲std :: array和std :: vector寫入其他字符。

+2

如果編譯器支持C++ 11構造函數繼承,也許只是使用'private'繼承,在構造函數中繼承。免責聲明:我還沒有嘗試過。 –

+0

如果你這樣不小心編寫它,那麼'std :: is_constructible :: value'對於任何'Args ...'選擇都是正確的,這可能是不可取的。 –

+0

也使用'VectorFunctionality(Args && ... args)'來隱含地轉發參數。在一般情況下,我不認爲這提供了一個很好和簡單的API。用戶不會輕易理解構造函數的用法,除非你有一個好的文檔。 –

回答

1

你必須小心一點,因爲可變參數構造函數可能會無意中匹配你不想要的東西。

採取以下(未經測試)的代碼:

VectorFunctionality<int> vf1; 
VectorFunctionality<int> vf2(vf1); // Unintentionally calls the templated constructor 

給定一個非const引用到VectorFunctionality,一個可變的構造是一個更好的匹配,因爲它不要求非const const的轉換,所以它被調用而不是複製構造函數。圍繞這一特定問題

一種方法是添加另一個構造,如:

VectorFunctionality(VectorFunctionality& that) : VectorFunctionality(static_cast<VectorFunctionality const&>(that)) {} 

注:也有這個問題的其他表現(例如,如果你有一個從VectorFunctionality派生的實例?)。

+1

複製構造永遠不會與構造函數模板匹配:上面的代碼將調用[默認]複製構造函數。即使它會調用模板構造函數,它實際上也會做正確的事情,即將呼叫轉發給成員。 –

+0

直接引用綁定而不是派生到基礎的轉換是完全匹配,cv-qualification不重要。它只與比較兩個參考綁定有關,對於OP的ctor模板而言並非如此。在這裏,我們有兩個精確匹配,但一個模板和一個非模板,因此選擇了非模板。 – dyp

+2

@DietmarKühl*「複製構造永遠不會與構造函數模板匹配」*我不確定這一點。一個ctor模板從來不被認爲是一個複製或移動ctor,但它可以通過重載解析來選擇,而不是採用'const&'AFAIK的慣用copy-ctor。這要求兩方都要參考。 [Live example](http://coliru.stacked-crooked.com/a/2046bb2278ff6896) – dyp

相關問題