Я пытаюсь настроить свои навыки создания шаблона (я очень мало знаю), создав библиотеку, содержащую матрицы и операции над этими матрицами. В принципе, я хочу, чтобы моя матрица была очень строго типизирована (тип данных и размер, известные во время компиляции), и я также хочу иметь возможность автоматически вычитать тип матрицы транспонирования.Специализируйте шаблон struct с классом шаблона как параметр
template< typename TDataType, size_t rows, size_t cols > class MyMatrix
Матриц могут быть вложенными, поэтому TDataType
может быть интегральным типом, но и MyMatrix<...>
самого по себе, в результате чего типа данных для транспонированной матрицы, чтобы быть не обязательно совпадает с одной из исходной матрицы, например: Transpose(MyMatrix< MyMatrix< char, 2, 3 >, 4, 6 >) ==> MyMatrix< MyMatrix< char, 3, 2 >, 6, 4 >
(тип данные внешней матрицы изменилась)
Моей первой попытки для транспонированного-типа отсчета была:
template< typename TDataType >
struct Transpose
{
typedef TDataType type;
};
template<>
struct Transpose< MyMatrix<TDataType, rows, cols> >
{
typedef MyMatrix<typename Transpose<TDataType>::type, cols, rows> type;
};
Я не нашел способа сделать это, потому что я не могу специализироваться на Transpose-шаблоне с MyMatrix (неизвестные и похожие ошибки TDataType).
Единственное компилируется решение, которое я придумал (я даже не знаю, работает ли он еще) это:
template< typename TMatrixType, typename TDataType, size_t rows, size_t cols >
struct Transpose
{
typedef TMatrixType type;
};
template< typename TDataType, size_t rows, size_t cols >
struct Transpose< MyMatrix<TDataType, rows, cols>, TDataType, rows, cols >
{
typedef MyMatrix< typename Transpose<TDataType,TDataType,rows,cols>::type, cols, rows > type;
};
Я считаю, что я делаю вещи слишком сложным; есть ли более легкое решение для достижения того, что я хочу?
Ответ на ответы на мой вопрос (я отправил вопрос без счета, так что я не хватает респ делать вещи обычным способом). Большое спасибо!
@Bo Persson @Will A: Я не намерен использовать это как библиотеку матриц общего назначения, я хочу выполнять операции над матрицами определенных (известных заранее) размеров и хочу видеть, где я могу получить, используя это подход. Это может позволить мне оптимизировать макет памяти для матриц (например, выравнивать строки-векторы на 32-байтных границах) и делать другие виды фанки. Я ожидаю, что застреваю себя в ногу очень много, делая это, но главное, что я пытаюсь получить здесь, это опыт и выяснить, что работает, а что нет (и что трудно сделать, а что нет «т).
@Bo Perrson: Я знаю, почему первая версия не компилируется, но мне было интересно, была ли более простая версия моей второй попытки, которая могла бы работать. Основная проблема заключается в том, что MyMatrix является самим шаблоном класса, и мне нужно каким-то образом передать его аргументы в Transpose-struct.
@VJo: Я не думаю, что это сработает. Если T является самой MyMatrix < ..>, тогда матрица транспонирования должна иметь Transpose<T>
как тип данных, а не сам T. Для всех основных типов (char, int, double ...) это, конечно, правильно и проще.
Вероятно, он думает, что компилятор может работать с открытым кодом на малых матрицах (и, таким образом, избегать накладных расходов цикла), когда границы константы компиляции. Возможно, он прав. – Nemo
@Nemo - ах, ОК - C++ - это не мое дело (не более) - так мне показалось странным. Спасибо Немо. –
В зависимости от вашего поля также может быть полезной дополнительная безопасность типов, а также возможность распределения кучи вашей базовой структуры данных без кучи. В конечном счете, более общее решение обычно является лучшим вызовом, но есть определенные аргументы в пользу уникальных типов. –