Как создать шаблонную функцию в классе? (C ++)

144

Я знаю, что можно сделать функцию шаблона:

template<typename T>
void DoSomeThing(T x){}

и можно сделать шаблон класса:

template<typename T>
class Object
{
public:
    int x;
};

но возможно ли сделать класс не в шаблоне, а затем сделать функцию в этом классе шаблоном? То есть:

//I have no idea if this is right, this is just how I think it would look
class Object
{
public:
    template<class T>
    void DoX(){}
};

или что-то в той степени, где класс не является частью шаблона, но функция?


источник

Ответы:

115

Ваше предположение является правильным. Единственное, что вы должны помнить, это то, что определение шаблона функции-члена (в дополнение к объявлению) должно быть в файле заголовка, а не в cpp, хотя это не обязательно должно быть в теле самого объявления класса.

Точно сказать не могу
источник
3
А также то, что вы не можете специализировать их. :-(
Фрэнк Крюгер
7
Не совсем верно. Определение может быть в файле cpp, если оно вызывается один раз для каждого уникального параметра шаблона n-uplet из не шаблонной функции / метода после его определения.
Бенуа
1
Следовательно, мое «следует» - держать его в заголовке - самый простой способ сделать это.
Не уверен
4
На самом деле, я считаю, что вы можете явно специализировать их, но вы не можете частично специализировать их. К сожалению, я не знаю, является ли это расширение для конкретного компилятора или стандарт C ++.
Патрик Джонмейер
7
Это на самом деле стандарт C ++. Вы можете сделать struct A {template <typename> void f (); }; шаблон <> void A :: f <int> () {}, например. Вы просто не можете специализировать их в области видимости класса, но вы можете делать это хорошо, когда это делается в области имен. (Не путать с областью, в которую фактически введена специализация: специализация все еще будет членом класса - но ее определение выполняется в области пространства имен. Часто область, в которую помещается что-то, совпадает с областью действия что-то определено в - но это иногда не соответствует действительности, как во всех случаях внеклассных определений)
Йоханнес Шауб - Litb
70

Смотрите здесь: Шаблоны , методы шаблонов , Шаблоны-члены, Шаблоны функций-членов

class   Vector
{
  int     array[3];

  template <class TVECTOR2> 
  void  eqAdd(TVECTOR2 v2);
};

template <class TVECTOR2>
void    Vector::eqAdd(TVECTOR2 a2)
{
  for (int i(0); i < 3; ++i) array[i] += a2[i];
}
никто
источник
хороший пример. но почему шаблон <typename T> находится внутри класса определени ... ???
Martian2049
@ Martian2049 Я полагаю, что это так, шаблон применяется только к функции-члену в классе, а не к классу в целом. Точно так же, как спросил ОП.
CBK
21

Да, функции-члены шаблона совершенно легальны и полезны во многих случаях.

Единственное предостережение в том, что функции-члены шаблона не могут быть виртуальными.

Тобиас
источник
9

Самый простой способ - поместить объявление и определение в один и тот же файл, но это может привести к превышению размера исполняемого файла. Например

class Foo
{
public:
template <typename T> void some_method(T t) {//...}
}

Также возможно поместить определение шаблона в отдельные файлы, т.е. поместить их в файлы .cpp и .h. Все, что вам нужно сделать, это явно включить создание экземпляра шаблона в файлы .cpp. Например

// .h file
class Foo
{
public:
template <typename T> void some_method(T t);
}

// .cpp file
//...
template <typename T> void Foo::some_method(T t) 
{//...}
//...

template void Foo::some_method<int>(int);
template void Foo::some_method<double>(double);
Привет
источник