Вы не можете сделать это только с помощью шаблона класса.Второй класс шаблонов и некоторое метапрограммирование необходимы для выполнения чего-то вроде этого:
#include <iostream>
template <int a, int b>
class Matrix_impl {
public:
// some functions
void g () {
std::cout << "hi" << std::endl;
}
};
template <int a>
class special_matrix_impl : public Matrix_impl<a,a> {
public:
void f () {
std::cout << "hello" << std::endl;
}
};
template<int a, int b>
struct which_template {
typedef Matrix_impl<a, b> type;
};
template<int a>
struct which_template<a, a> {
typedef special_matrix_impl<a> type;
};
template<int a, int b>
using Matrix=typename which_template<a, b>::type;
int main () {
Matrix <3,3> m;
m.f();
m.g();
}
Реальные имена шаблонов здесь Matrix_impl
и special_matrix_impl
, а Matrix<a,b>
выбирает подходящий.
В качестве альтернативы, единственный способ сделать это с одним шаблоном - это использовать дополнительный, по умолчанию, параметр шаблона для устранения неоднозначности специализации шаблона:
#include <iostream>
template <int a, int b, typename=void>
class Matrix {
public:
// some functions
void g () {
std::cout << "hi" << std::endl;
}
};
template <int a>
class Matrix <a, a, void> : public Matrix <a, a, int> {
public:
void f () {
std::cout << "hello" << std::endl;
}
};
int main () {
Matrix <3,3> m;
m.f();
m.g();
}
Довольно уродливо, но может оказатьсяуборщик в конце, если потребуется несколько специализаций.