Como criar uma função de modelo dentro de uma classe? (C ++)

144

Eu sei que é possível fazer uma função de modelo:

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

e é possível criar uma classe de modelo:

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

mas é possível transformar uma classe fora de um modelo e depois transformar uma função nessa classe em um modelo? Ou seja:

//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(){}
};

ou algo na medida em que a classe não faz parte de um modelo, mas a função é?


fonte

Respostas:

115

Seu palpite é o correto. A única coisa que você deve lembrar é que a definição do modelo da função de membro (além da declaração) deve estar no arquivo de cabeçalho, não no cpp, embora não precise estar no corpo da própria declaração de classe.

Não tenho certeza
fonte
3
E também que você não pode especializá-los. :-(
Frank Krueger
7
Não é exatamente verdade. A definição pode estar em um arquivo cpp, desde que seja chamada uma vez para cada parâmetro de modelo exclusivo n-uplet a partir de uma função / método que não seja do modelo após a definição.
Benoît
1
Daí o meu "deveria" - mantê-lo no cabeçalho é a maneira mais simples de conseguir isso.
Não tenho certeza
4
Na verdade, acredito que você pode explicitamente especializá-las, mas não pode parcialmente. Infelizmente, não sei se essa é uma extensão específica do compilador ou o padrão C ++.
Patrick Johnmeyer
7
Na verdade, é c ++ padrão. Você pode fazer struct A {template <typename> void f (); }; template <> void A :: f <int> () {} por exemplo. Você simplesmente não pode especializá-los no escopo da classe, mas pode fazê-lo bem quando feito no escopo do espaço para nome. (para não confundir com o escopo em que a especialização é realmente inserida: a especialização ainda será um membro da classe - mas sua definição é feita no escopo do espaço para nome. Geralmente, o escopo em que algo é colocado é o mesmo que o escopo algo é definido em - mas isso às vezes não é verdade, como em todos os casos de definições fora da classe)
Johannes Schaub - litb 10/10/09
70

Veja aqui: Modelos , métodos de modelo , Modelos de Membro, Modelos de Função de Membro

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];
}
Nenhum
fonte
bom exemplo. mas por que o template <typename T> está dentro da classe definitino ... ???
Martian2049
@ Martian2049 Acredito que seja assim, o modelo se aplica apenas à função de membro da classe, e não à classe como um todo. Exatamente como o OP pediu.
CBK
21

Sim, as funções de membro do modelo são perfeitamente legais e úteis em várias ocasiões.

A única ressalva é que as funções de membro do modelo não podem ser virtuais.

Tobias
fonte
9

A maneira mais fácil é colocar a declaração e a definição no mesmo arquivo, mas isso pode causar um excesso de tamanho no arquivo executável. Por exemplo

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

Além disso, é possível colocar a definição do modelo em arquivos separados, ou seja, colocá-los nos arquivos .cpp e .h. Tudo o que você precisa fazer é incluir explicitamente a instanciação do modelo nos arquivos .cpp. Por exemplo

// .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);
Ei
fonte