2014-09-11 56 views
1

創建具體類說我有一個模板類:如何從一個模板類

template <typename T> class StringDeque: 
public std::deque<T> 
{ 
public: 

    ... 

private: 
    typedef std::deque<T> BaseClass; 
}; 

說我想創建具體類ArrayString其中T=std::string。 什麼是正確的方式來實現這一目標:

定義

#define ArrayString StringDeque<string> 

的typedef

typedef StringDeque <string> ArrayString; 

繼承

class ArrayString : 
    public StringDeque <string> {}; 

我不確定是否所有的建議都有效。無論如何,我試圖找出哪種做法最適合。

+0

我不認爲typedef適用於模板,但你可以說'使用ArrayString = StringDeque ;' – Melkon 2014-09-11 07:03:38

+1

@Melkon Typedef適用於類型,類模板的實例化是一種類型,所以它工作得很好。 – Angew 2014-09-11 07:07:23

回答

1

正確方法:

typedef std::deque<std::string> StringDeque; 
using StringDeque = std::deque<string>; 

這就是說,這裏是你的問題更多一些注意事項:

您寫道:

template <typename T> class StringDeque: public std::deque<T> // ... 

std容器類並不意味着作爲基類。這意味着它們不應該被繼承(並且從UB繼承)。

當您想在另一個類中使用std容器功能時,答案應始終爲封裝。這意味着,建立在的std ::隊列的類中的功能正確的方法是:

template<typename T> class StringDequeue { 
    std::deque<T> storage; 
public: 
    // add interface here that uses storage 
}; 

也提出了這一點:

#define ArrayString StringDeque<string> 

請千萬不要用定義來聲明一個類型。它有效,但它有它自己的陷阱,在C++中被認爲是不好的做法。

2

你想給一個特定類型的名稱(這恰好是一個模板的實例化)。 C++的方式,讓名(別名)類型是一個typedef:

typedef StringDeque<string> ArrayString; 

或者,因爲C++ 11,用別名聲明:

using ArrayString = StringDeque<string>; 

邊注:當考慮這些東西,通常有助於按照正確的模板術語進行思考。您沒有「模板類」(具有特殊屬性的),您具有「類模板」(用於創建類的模板)。該模板不是一種類型;它的實例化。

1

typedef創建類型別名或(因爲C++ 11)using

typedef StringDeque<std::string> ArrayString; 
using ArrayString = StringDeque<std::string>; 

預處理器是大錘:偶爾有用的,但,沒有的語言級別的結構的知識,容易產生斷線代碼在令人驚訝的方式。在這種情況下,我認爲唯一的問題是名稱不會受限於任何範圍;但這足以避免它。

繼承創建一個新類型;雖然它通常在基類型的地方可用,但它不是完全可互換的,並且不會從基類型繼承任何構造函數。所以這也不是你想要的簡單類型別名。