template <typename T> class Matrix {
public:
// ...
template <typename U> Matrix(Matrix<U> const&);
// ...
private
unsigned int m_rows, m_cols;
T *m_data;
// ...
};
通過將適當的類型轉換添加到複製構造函數中,此方法在不同類型的矩陣之間完美轉換。令人驚訝的是,在一個簡單的複製構造函數會起作用的情況下,它會失敗並出現malloc錯誤:其中U == T
。果然,使用默認的Matrix<T>::Matrix(Matrix<T> const&)
簽名重載複製構造函數可以解決問題。
這是一個糟糕的解決方案,因爲它導致了複製構造函數代碼的批量複製(字面上是不變的複製和粘貼)。更重要的是,我不明白爲什麼沒有重複代碼時出現雙免費malloc
錯誤。此外,爲什麼在這裏需要非常詳細的template <typename T> template <typename U>
語法而不是標準,並且簡潔得多,template <typename T, typename U>
?
模板化方法的完整源代碼,在Mac OS 10.5上使用G ++ v4.0.1編譯。
template <typename T> template <typename U> Matrix<T>::Matrix(Matrix<U> const& obj) {
m_rows = obj.GetNumRows();
m_cols = obj.GetNumCols();
m_data = new T[m_rows * m_cols];
for (unsigned int r = 0; r < m_rows; ++r) {
for (unsigned int c = 0; c < m_cols; ++c) {
m_data[m_rows * r + c] = static_cast<T>(obj(r, c));
}
}
}
您對malloc錯誤的解釋聽起來很明顯。編譯器不能使用模板成員函數作爲複製構造函數是否存在特定的原因?感謝您提供的信息和建議以避免代碼重複。 – 2009-08-09 00:32:29
如果你有這個模板,那它還不是一個功能。只有使用某個模板參數才能生成(成員函數)(稱爲專業化)。這也是成員模板不能成爲虛擬的原因:您不能預先知道從中生成了哪些功能。 – 2009-08-09 01:02:02
這非常有道理 - 這不適用於需要轉發聲明模板參數或包含實現的完整源代碼的原因。再次感謝。 – 2009-08-09 03:33:15