Отвечаю на вопрос из комментариев. Можно сделать так:
template <int a, int b>
class A {
public:
template<bool tmp = true>
typename std::enable_if<a==b && tmp, int>::type F() {
return 1;
}
};
...
A<1,1> a;
std::cout << a.F(); // OK.
A<2,100> b;
std::cout << b.F(); // Ошибка A<2,100> не имеет метода F().
Мне сложно объяснить, чтобы было понятно, почему работает именно это, но я попробую.
Во-первых, метод дложен быть обернут в шаблон, потому что если там будет ошибка, то не инстанцируется шаблон для вашего типа Matrix, а он должен быть даже если размерности не равны.
Далее, хотелось бы что бы просто работало вот это:
template<>
typename std::enable_if<a==b, int>::type F()
Тут все понятно, enable_if не имеет type, если a неравно b. Шаблон никак не инстанциировать и метод не должен был бы генерироваться. Но это было бы слишком просто.
Вместо этого, надо там завести какой-то вообще ненужный как бы параметр шаблона tmp, и обязательно использовать его в enable_if. Это потому что если в этом шаблоне не будет никак использоваться параметр шаблона, то SFINAE не срабатывает, и вылезает ошибка компиляции.