Qual é a diferença entre uma classe de modelo e um modelo de classe?

88

Qual é a diferença entre uma classe de modelo e um modelo de classe?

codificador
fonte

Respostas:

127

Este é um ponto comum de confusão para muitos (incluindo a página de Programação Genérica na Wikipedia, alguns tutoriais C ++ e outras respostas nesta página). No que diz respeito ao C ++, não existe uma "classe de modelo", existe apenas um "modelo de classe". A maneira de ler essa frase é "um modelo para uma classe", em oposição a um "modelo de função", que é "um modelo para uma função". Novamente: classes não definem modelos, modelos definem classes (e funções). Por exemplo, este é um modelo , especificamente um modelo de classe , mas é não uma classe :

template<typename T> class MyClassTemplate
{ 
    ...
};

A declaração MyClassTemplate<int> é uma classe, ou pedantemente, uma classe baseada em um modelo. Não há propriedades especiais de uma classe baseada em um modelo em comparação com uma classe não baseada em um modelo. As propriedades especiais são do próprio modelo .

A frase "classe de modelo" não significa nada, porque a palavra "modelo" não tem significado como adjetivo quando aplicada ao substantivo "classe" no que diz respeito a C ++. Implica a existência de uma classe que é (ou define) um modelo , o que não é um conceito existente em C ++.

Eu entendo a confusão comum, pois provavelmente se baseia no fato de que as palavras aparecem na ordem "classe de modelo" no idioma real, o que é uma história totalmente diferente.

Não tenho certeza
fonte
+1. Às vezes é útil por qualquer motivo distinguir a "origem" de uma classe, caso em que você pode usar razoavelmente o termo "classe de modelo" - mas pelas razões que você deu, é uma boa ideia definir cuidadosamente o que você quer dizer com isso .
j_random_hacker
1
@j_random_hacker - veja a resposta de litb abaixo, mas em resumo, o termo preferido para isso é "especialização de modelo de classe"
Não tenho certeza
@Não tenho certeza: Bem, na verdade eu acho "especialização de modelo de classe" um pouco ambígua, uma vez que também pode se referir ao processo de definição de uma especialização explícita ou parcial para um modelo - algo que não é necessário para produzir uma "classe" real. :) IMHO "instanciação do modelo de classe" é o termo mais claro.
j_random_hacker
2
@j_random_hacker: Existe um termo apropriado para isso - "especialização de modelo de classe explícita" e "especialização de modelo de classe explícita parcial". Pesado, mas não ambíguo :)
Não tenho certeza
1
-1 Os termos significam o que significam para as pessoas que os usam. Começar a analisar os significados literais não tem sentido. Experimente com qualquer outro termo da vida diária ou da engenharia. Resumindo, essa resposta é besteira. A resposta de SHH , citando Bjarne, está OK.
Saúde e hth. - Alf
15

Bjarne Stroustrup, o criador do C ++, diz em seu livro The C ++ Programming Language 4ª edição , 23.2.1 Definindo um modelo:

Existem pessoas que fazem distinções semânticas entre os termos modelo de classe e classe de modelo . Eu não; isso seria muito sutil: considere esses termos intercambiáveis. Da mesma forma, considero o template de função intercambiável com a função de template .

SHH
fonte
13

A diferença é que o termo "classe de modelo" simplesmente não existe no padrão C ++. É um termo usado principalmente por pessoas que acham que o termo "modelo de classe" é confuso (como as empresas de Qt Nokia e anteriormente Trolltech).

O Standard não tem conceito disso, então cabe a outras pessoas fazer a diferença. Algumas pessoas o usam como sinônimos, e outros dizem que o termo "classe de modelo" se refere a um modelo de classe instanciado ou explicitamente especializado, o que o tornaria equivalente ao termo "especialização de modelo de classe". Historicamente, tinha esse significado. O Manual de Referência Anotado define na página 343

Uma classe gerada a partir de um modelo de classe é chamada de classe de modelo, pois é uma classe definida especificamente com um nome de classe de modelo como seu nome

O template-class-name não terminal é equivalente ao template-id não terminal usado no padrão de hoje e diminui template-name < arguments >.


Para se familiarizar com os termos atuais, o que é mais importante do que usar termos antigos duvidosos

// (1) defines a class template
template<typename T> class A { }; 

// (2) defines a class template explicit specialization 
template<> class A<int> { };

// (3) defines a class template partial specialization
template<typename T> class A<T*> { };

// (4) explicitly instantiates A<char>. 
template class A<char>;

// (5) implicitly instantiates A<short> (because of the member declaration)
struct D { A<short> a; };
  • O ARM chamou a classe (2) e as classes geradas por (4) e (5) uma classe de modelo . Não tenho certeza se o ARM já sabia sobre especializações parciais. Mas se for assim, (3) não foi chamada de classe de modelo, porque (3) não define uma classe, mas define um modelo.
  • O padrão atual chama a classe (2) e os gerados por (4) e (5) especializações de modelo de classe . E (3) é chamado de especialização parcial , em oposição a uma especialização explícita . Às vezes também chama (3) uma especialização (3.2 / 5 - porém com ligações cruzadas de esclarecimento), embora eu ache que isso não seja totalmente claro para mim, uma vez que define uma "especialização" como sendo uma "classe, função ou classe membro ", que (3) não satisfaz.
Johannes Schaub - litb
fonte
3
Ele Ele. Sim e vários outros ainda contribuem para esse conjunto. Notavelmente o C ++ Faq Lite e a documentação do Qt. O autor do faq lite me disse em um e-mail que deseja colocar outro item do FAQ explicando que usar a palavra "especialização" é melhor, pois causa menos confusão (usando "especialização explícita" para o tipo de especialização escrita pelo usuário, então). Os caras do Qt me disseram que não querem usar o termo "modelo de classe" .... eles acham muito "antinatural". Que pena.
Johannes Schaub - litb
@ JohannesSchaub-litb: O ARM foi escrito por Bjarne Stroustrup e Margaret Ellis, por volta de 1991 do IIRC. Sua citação do ARM contradiz a citação de SHH da 4ª edição do TCPPL de Bjarne . Portanto, é bom que você faça uma distinção entre a terminologia antiga (pré-padrão) e a atual.
Saúde e hth. - Alf
6

Uma classe de modelo está relacionada ao padrão de design do Método de modelo , enquanto o modelo de classe é apenas um modelo de classe de "preencher as lacunas".

Peter Perháč
fonte
1

Um modelo de classe é um modelo usado para gerar classes, enquanto uma classe de modelo é uma classe produzida por um modelo.

DEBALINA MAHATA
fonte
0

Classe de modelo: uma classe que possui definição genérica ou uma classe com parâmetros que não é instanciada até que a informação seja fornecida pelo cliente. É referido como um jargão para templates simples. Simplesmente classe com template de prefixo e uso de T. Modelo de classe: A construção individual de uma classe é especificada por um modelo de classe que é quase semelhante à maneira como os objetos individuais são construídos usando uma classe. É referido a um objeto da classe de modelo Ex- classname objectname (lista de argumentos)

Rishabh
fonte
0

O modelo de classe é uma classe genérica para diferentes tipos de objetos. Basicamente, ele fornece uma especificação para gerar classes com base em parâmetros. Sempre que um novo objeto é criado, uma nova classe ocorrerá na memória para esse propósito. Isso é chamado de instanciar um modelo de classe e cada versão instanciada da classe é chamada de classe de modelo.

BlackList96
fonte
0

Dê uma olhada neste artigo (da wg21 e foi publicado em 1992) :

Terminologia Consistente

Muito do argumento e desacordo até agora, tem sido com relação à terminologia usada no capítulo que descreve os modelos. Mais frequente tem sido a aplicação variável de 'função-modelo' e 'modelo-função' para expressar diferentes idéias e intenções. Visto que nenhuma nomenclatura consistente é aplicada, o resultado é confusão e argumento.

Para fins deste documento, como proposta de adoção formal pelo comitê nas discussões sobre modelos, e para fins de esclarecimento da documentação; Proponho que adotemos a formalização, que um '-template' final descreve um conjunto de tipos ou funções descritas por um modelo. E que um 'template-' inicial é usado para descrever a definição do template de parte de um '-template' , como um 'template-member-function'. Portanto :-

  • 'function-template': Um conjunto de funções descritas por um template, paramétricas em alguma informação de tipo fornecida como argumento para aquele template. Por exemplo :-
template<class T> int nullcheck( T* pT )
{ return ( pT != 0 ); }
  • 'modelo de classe': Um conjunto de classes descrito por um modelo, paramétrico em algumas informações de tipo fornecidas como argumento para esse modelo. Por exemplo :-
template<class T> class S {
int i;
public:
int sep_member();
int imm_member()
{ return 2; }
}
  • 'template-function': este termo não é mais permitido. **
  • 'template-class': este termo não é permitido. **

  • 'template-function-membro': Este termo não é permitido, pois descreve uma propriedade não suportada atualmente pela definição do template. Usando a convenção de terminologia acima, isso descreveria um membro de um modelo de não classe, cuja definição era ela própria um modelo. Por exemplo :-

class Normal { public:
template<class T> int foo(T*pT)
{ return ( pT == 0 ); }
};

No entanto, como os modelos estão atualmente limitados ao escopo global, tal modelo é inválido.

  • 'template-static-member-function':
  • 'template-member-function':
  • 'template-static-member':
  • 'template-static-data-member ' template-member ': termos alternativos para a definição de um membro aparecendo separado do' modelo de classe 'ao qual pertence. Por exemplo :-
template<class T> int S<T>::sep_member()
{ return i; }
陳 力
fonte
Sobre a Normalclasse que você descreveu acima: Eu não sabia que esse modelo de função de membro era proibido. É aceito por todos os compiladores que experimentei. o que estou perdendo?
dan_din_pantelimon