Как некоторые из моего кода требуется неявное преобразование между матрицами различных типов (например, Matrix<int>
к Matrix<double>
), я определил шаблонный конструктор копирования Matrix<T>::Matrix(Matrix<U> const&)
вместо стандартного Matrix<T>::Matrix(Matrix<T> const&)
:Templated копирование конструктор не может с определенным шаблонным типом
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>
?
Полный источник шаблонного метода, скомпилированный с использованием G ++ v4.0.1 на Mac OS 10.5.
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 появляются. Существует ли конкретная причина, почему компиляторы не могут использовать функцию-член шаблона в качестве конструктора-копии? Спасибо за информацию и за советы, чтобы избежать дублирования кода. –
Если у вас есть этот шаблон, это еще не функция. Только его использование с некоторым аргументом шаблона генерирует из него (член) функцию (называемую специализацией). Это также причина, по которой шаблоны членов не могут быть виртуальными: вы заранее не знаете, какие функции генерируются из него. –
Это имеет большой смысл - это не работает по той причине, что нужно либо переслать объявить параметры шаблона, либо включить полный источник реализации. Еще раз спасибо. –