Зачем использовать специализированный класс шаблонов?


Это произошло в русле мысли, следующей за шаблонной специализацией или условными выражениями?.

Я использую специализацию шаблона в своем проекте и наткнулся на этот пример из 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 2

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 ) { ...

То есть, даже если вам нужно явно создать различные типы, механизм специализации позволяет вам предоставить одно имя, которое можно использовать в общем виде для управляйте различными типами, как если бы они были просто вариантами одного типа.