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 é?

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.


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];
}

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.


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);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.