Зачем использовать специализированный класс шаблонов?
Это произошло в русле мысли, следующей за шаблонной специализацией или условными выражениями?.
Я использую специализацию шаблона в своем проекте и наткнулся на этот пример из Stroustrup: Matrix.h , где он объявляет класс шаблона MatrixBase
template<class T> class Matrix_base
Для общих элементов и матричного шаблона класса
template<class T = double, int D = 1> class Matrix
Как "опора" (что бы это ни было) для специализации. Он объявляет конструктор частным, так что только специализации могут быть инстанцированы. Они объявляются:
template<class T> class Matrix<T,1> : public Matrix_base<T> {...};
template<class T> class Matrix<T,2> : public Matrix_base<T> {...};
template<class T> class Matrix<T,3> : public Matrix_base<T> {...};
Мой вопрос таков: в таком случае, в чем преимущество специализации? Очевидно, что нет кода, который эти три специализации имеют в общем, так почему бы не вырезать общий шаблон и объявить:
template<class T> class Matrix_1<T> : public Matrix_base<T> {...};
template<class T> class Matrix_2<T> : public Matrix_base<T> {...};
template<class T> class Matrix_3<T> : public Matrix_base<T> {...};
?
2 ответа:
потому что, имея второй параметр шаблона, можно использовать специализации , а также общую, неспециализированную реализацию. ИтакMatrix<float, 1000> m;
Может сделать что-то разумное, но не специализированное, тогда как вам придется определить
Matrix_1000<T>
. Edit : первый пункт применим в общем случае, но не к этому конкретному случаю, где общий случай имеет частный конструктор.Кроме того, он позволяет вам делать такие вещи, как
Matrix<double, SOME_CONSTANT> m;
Который ты не могу сделать с вашим решением
_N
.
В основном ответ заключается в том, что вы можете использовать шаблон в общем коде. Вы можете использовать константу времени компиляции для изменения поведения программы, или вы можете написать универсальный код, который будет обрабатывать различные версии класса
Matrix
, которые не могут быть обработаны, если типы имеют разные имена:template <typename T, int D> void print( std::ostream& o, Matrix<T,D> const & m ) { ...
То есть, даже если вам нужно явно создать различные типы, механизм специализации позволяет вам предоставить одно имя, которое можно использовать в общем виде для управляйте различными типами, как если бы они были просто вариантами одного типа.