Проблема в том, что вы пытаетесь использовать частичную специализацию всего класса , не имея определенного частично специализированного класса.
Если print
Если бы сам шаблон функции был, ситуация была бы другой, потому что вы действительно можете специализировать шаблоны функций.Однако ваша конструкция имеет только весь класс в качестве шаблона.
Это означает, что template <typename T, int n> class Storage<T, n>
и template <int n> class Storage<int, n>
- это совершенно разные, не связанные классы.Таким образом, вы должны сначала определить последний класс:
template<int n> class Storage<int, n>
{
// define everything
};
template<int n> void Storage<int, n>::print() { /* implement */ }
Учтите, что частичная специализация Storage<int, n>
может быть совершенно другим классом от первичного шаблона и может иметь совершенно другой членфункции.У компилятора нет возможности узнать это, пока вы не определите этот класс.
После комментария sbi вот одна из идей:
//... in the class definition
template<typename S, int m> friend void print_helper(const Storage<S, m> &);
template<int m> friend void print_helper(const Storage<int, m> &);
void print() { print_helper(*this); }
// outside:
template <typename S, int size> void print_helper(const Storage<S, size> & s)
{
// ...
}
template <int size> void print_helper(const Storage<int, size> & s)
{
// ...
}
Вместо friend
вы также можете сделать шаблон вспомогательной функции static
, но это может привести к значительному увеличению объема кода, поскольку у вас будет два статических шаблона функций для каждого типа класса, а не только два глобально.