2012-05-17 93 views
0

我有下面的類:添加一個構造函數模板專業化

template <typename T> 
class Fixed2DContainer { 

    T* ptr; 

public: 
    const int total_cols; 
    const int total_rows; 

    Fixed2DContainer(int cols, int rows); 
    T& operator()(int col_n, int row_n); 
    ~Fixed2DContainer(); 

private : //disallow copy 
    Fixed2DContainer& operator=(const Fixed2DContainer&); 
    Fixed2DContainer operator()(const Fixed2DContainer&); 
}; 

現在,我想專攻這個模板對於一些類,以便唯一的變化是,我可以有另一個構造。 基本上我希望能夠做到:

Fixed2DContainer<Image>("filename.jpg"); 

是有一種優雅的方式來做到這一點?我是相當新的模板,所以我沒有任何難度

+0

不,你不能這樣做根本。你必須重新編寫整個班級作爲專門練習,並添加新的構造函數。您可以將大部分功能移出到主模板和專用化都使用的單獨基類中,以避免重複這一切,但大多數「功能」似乎是構造函數和複製操作,它們需要重新構建無論如何。 'ptr'和'total_cols' /'total_rows'成員可以在共同的基礎上,但是一旦您將基礎構造等添加到基礎中,您可能無法節省大量工作 –

+0

這看起來像是一個很好的舊OO而不是模板專業化。 –

回答

1

下面是我在我先前的評論意味着一個簡單的例子的想法...

template <typename T> 
class Fixed2DContainerBase { 

    T* ptr; 

public: 
    const int total_cols; 
    const int total_rows; 

    Fixed2DContainerBase(int cols, int rows); 
    T& operator()(int col_n, int row_n); 
    ~Fixed2DContainerBase(); 

private : //disallow copy 
    Fixed2DContainerBase& operator=(const Fixed2DContainerBase&); 
    Fixed2DContainerBase(const Fixed2DContainerBase&); 
}; 

// primary template 
template <typename T> 
class Fixed2DContainer : public Fixed2DContainerBase<T> { 

    Fixed2DContainer(int cols, int rows); 
    ~Fixed2DContainer(); 
}; 

// explicit specialization 
template <> 
class Fixed2DContainer<Image> : public Fixed2DContainerBase<Image> { 

    Fixed2DContainer(int cols, int rows); 
    Fixed2DContainer(const std::string&); 
    ~Fixed2DContainer(); 
}; 

注:因爲基類是不可複製的,所以派生類也是如此。如果所有清理操作都可以由基本析構函數完成,那麼在派生類中定義析構函數可能沒有必要。

0

我自己也有同樣的問題。不幸的是,每個構造函數都必須存在於通用模板中。儘管可以避免在運行時使用錯誤構造函數的人;

template <typename T> 
class Fixed2DContainer { 

    // omitted 

    Fixed2DContainer(string fileName) 
    { 
     // Do not allow construction of Fixed2DContainer with 
     // string argument in general case 
     ASSERT(false); 
     // or 
     throw new ExceptionType("Not implemented"); 
    } 

    // omitted 
}; 

template<> 
class Fixed2DContainer<Image> { 

    // omitted 

    Fixed2DContainer(string fileName) 
    { 
     // Actual construction code 
    } 

    // omitted 
}; 

斷言是首選,因爲你的代碼將在斷言突破,而在例外情況下,它會打破漁獲,使其稍硬調試。

3

如果你的編譯器支持它,C++ 11 繼承構造將幾乎把你帶到任何你想成爲:

template <typename T> 
class Base {};    // has all the implementation 

template <typename T> 
class Template { 
    using Base::Base; 
    //Template() = delete; // You might need this if you don't want 
          // the default constructor 
}; 

template <> 
class Template<int> { 
    using Base::Base; 
    Template(std::string const & x) {} 
    //Template() = delete; // You might need this if you don't want 
          // the default constructor 
};