|
||||
|
Техника симуляции Естественным первым шагом будет вынести различающуюся функциональность Matrix‹› в два базовых класса: Matrix_‹›, реализующий общий случай, и Matrix_float_‹› для специфики Matrix‹float,…›. template‹class T, int Rows, int Columns› class Matrix_ { //… }; template‹int Rows, int Columns› class Matrix_float_ { //… }; Таким образом, проблема сведется к тому, чтобы класс Matrix‹T, Rows, Columns› наследовался от Matrix_‹T, Rows, Columns› или Matrix_float_‹Rows, Columns›, в зависимости от того, является ли параметр T шаблона Matrix‹› типом float. Решение этой задачи и является главным «фокусом» данной техники. Несмотря на отсутствие поддержки частичной специализации, компилятор позволяет специализировать шаблоны полностью. Этот факт можно использовать для построения вложенных шаблонов с полной специализацией и выбором подходящего базового класса на соответствующем уровне вложенности. template‹class T› struct MatrixTraits { template‹int Rows, int Columns› struct Dimensions { typedef Matrix_‹T, Rows, Columns› Base; }; }; template‹› struct MatrixTraits‹float› { template‹int Rows, int Columns› struct Dimensions { typedef Matrix_float_‹Rows, Columns› Base; }; }; Теперь осталось просто унаследовать Matrix‹› от соответствующего класса MatrixTraits‹›::…::Base. template‹class T, int Rows, int Columns› class Matrix: public MatrixTraits‹T›::template Dimensions‹Rows, Columns›::Base { //… }; ПРИМЕЧАНИЕ Согласно текущей версии стандарта, использование ключевого слова template при квалификации вложенного шаблона Dimensions в данном случае обязательно, хотя некоторые компиляторы и позволяют его опускать. |
|
||
Главная | В избранное | Наш E-MAIL | Добавить материал | Нашёл ошибку | Наверх | ||||
|