Не компилируется специализация шаблона

Serg_77m
Дата: 31.03.2015 19:22:46
Доброго времени суток.

С C++ раньше дела имел очень мало, а шаблоны только изучаю. Вот какая проблема возникла.
Имеется шаблон класса XColumn<typename type> - некий контейнер для type. В нём имеется метод toString(), что-то возвращающий.
template<typename T>
class XColumn {
  T ccc;
public:
  const char * toString() const { return "foo"; }
};

Имеется шаблон для другого класса - Int<int size> - что-то вроде вектора фиксированного размера.
template<int N>
struct Int {
  int data[N];
};

Хочется поместить этот вектор в контейнер. Получается.
XColumn<Int<8> > c3;

Но проблема в том, что стандартный шаблонный метод toString() для вектора не подходит, нужна специализация. Пишу:
template<int N>
const char * XColumn<Int<N> >::toString() const { return "I'm is int<N>"; }

И вот тут компилятор (g++ 4.4.0) выдаёт ошибку: Invalid use of incomplete type 'class XColumn<Int<N> >
Смутно догадываюсь почему, но нет никаких идей как исправить. Возможно ли это вообще?

Полный код:
+
#include <stdio.h>

template<typename T>
class XColumn {
  T ccc;
public:
  const char * toString() const { return "foo"; }
};

template<int N>
struct Int {
  int data[N];
};

template<>
const char * XColumn<double>::toString() const { return "I'm is double"; }

template<int N>
const char * XColumn<Int<N> >::toString() const { return "I'm is int<N>"; }

int main() {
  XColumn<int> c1;
  XColumn<double> c2;
  XColumn<Int<8> > c3;

  printf("%s\n", c1.toString());
  printf("%s\n", c2.toString());
  printf("%s\n", c3.toString());

  return 0;
}
Dimitry Sibiryakov
Дата: 31.03.2015 19:31:57

Шаблоны тут не нужны, наследования хватит за глаза.

Posted via ActualForum NNTP Server 1.5

MasterZiv
Дата: 31.03.2015 19:41:54
Serg_77m,

для начала ты не то параметризируешь....
Serg_77m
Дата: 31.03.2015 19:54:29
Dimitry Sibiryakov
Шаблоны тут не нужны, наследования хватит за глаза.
Это упрощённый тестовый пример. На самом деле XColumn наследуется от абстрактного класса, содержит десяток виртуальных методов и в качестве контейнера использует около десятка разных типов. И почти все методы ко всем типам подходят. Кроме шаблонного Int<N>, для которого пара методов нужна другая. Практически задача решается клонированием шаблона XColumn<typename T> в шаблон XColumnInt<int N> и дублированием всех методов с модификацией нужных. Их не так-то и много. Интерес скорее академический: что не так и как ещё можно решить?
Anatoly Moskovsky
Дата: 31.03.2015 22:27:52
Serg_77m,

Перед определением метода специализированного класса вам надо написать определение самой этой специализации.
Anatoly Moskovsky
Дата: 31.03.2015 22:28:44
Т.е. вы не можете специализировать только один метод - надо специализировать весь класс.
Serg_77m
Дата: 01.04.2015 09:20:00
Anatoly Moskovsky
Т.е. вы не можете специализировать только один метод - надо специализировать весь класс.
Хм... а специализацию toString() для double проглатывает... Или это нарушение стандарта?
Anatoly Moskovsky
Дата: 01.04.2015 10:03:44
Serg_77m
Anatoly Moskovsky
Т.е. вы не можете специализировать только один метод - надо специализировать весь класс.
Хм... а специализацию toString() для double проглатывает... Или это нарушение стандарта?

Я не совсем точно выразился.
Нельзя частично специализировать метод/функцию.
Полностью специализировать можно.
Полная специализация - это когда нет параметров:
template<> ...
Anatoly Moskovsky
Дата: 01.04.2015 10:04:38
Хотя некоторые компиляторы позволяют частичную специализацию функций, но gcc обычно строг ))
Serg_77m
Дата: 01.04.2015 17:30:21
Anatoly Moskovsky
Serg_77m
пропущено...
Хм... а специализацию toString() для double проглатывает... Или это нарушение стандарта?

Нельзя частично специализировать метод/функцию.
Полностью специализировать можно.
Полная специализация - это когда нет параметров:
template<> ...
Ага, понятно. Спасибо.