Use ‘class’ ou ‘typename’ para parâmetros de modelo?

Duplicar Possível:
C ++ diferença de palavras-chave ‘typename’ e ‘class’ em modelos

Ao definir um modelo de function ou modelo de class em C ++, pode-se escrever isto:

template  ... 

ou pode-se escrever isso:

 template  ... 

Existe uma boa razão para preferir um ao outro?


Aceitei a resposta mais popular (e interessante), mas a resposta real parece ser “Não, não há uma boa razão para preferir uma sobre a outra”.

  • Eles são equivalentes (exceto conforme indicado abaixo).
  • Algumas pessoas têm motivos para usar sempre o nome de typename .
  • Algumas pessoas têm motivos para usar sempre a class .
  • Algumas pessoas têm motivos para usar os dois.
  • Algumas pessoas não se importam com qual delas usam.

Observe, no entanto, no caso de parâmetros de modelo de modelo , o uso de class vez de typename é necessário. Veja a resposta de user1428839 abaixo. (Mas este caso particular não é uma questão de preferência, é um requisito da linguagem.) (Também isto irá mudar com c++17 )

Stan Lippman falou sobre isso aqui . Eu pensei que fosse interessante.

Resumo : Stroustrup usou originalmente a class para especificar tipos em modelos para evitar a introdução de uma nova palavra-chave. Alguns no comitê preocuparam-se que esta sobrecarga da palavra-chave levasse à confusão. Posteriormente, o comitê introduziu uma nova palavra-chave typename para resolver a ambigüidade sintática e decidiu permitir que ela também fosse usada para especificar tipos de modelo para reduzir a confusão, mas para compatibilidade com versões anteriores, a class mantinha seu significado sobrecarregado.

De acordo com Scott Myers, Effective C ++ (3ª ed.) Item 42 (que deve, claro, ser a resposta final) – a diferença é “nada”.

O conselho é usar “class” se for esperado que T sempre será uma class, com “typename” se outros tipos (int, char * whatever) forem esperados. Considere isso como uma dica de uso.

Como uma adição a todas as postagens acima, o uso da palavra chave class é forçado (até e incluindo C ++ 14) ao lidar com parâmetros de template , por exemplo:

 template  

Neste exemplo, o typename Container teria gerado um erro do compilador, algo assim:

 error: expected 'class' before 'Container' 

Eu prefiro usar typename porque eu não sou um fã de palavras-chave sobrecarregadas (jeez – quantos significados diferentes o static tem para vários contextos diferentes?).

Há uma diferença e você deve preferir class ao typename .

Mas por que?

typename é ilegal para argumentos de template, então, para ser consistente, você deve usar class :

 template typename MyTemplate, class Bar> class Foo { }; // :( template class MyTemplate, class Bar> class Foo { }; // :) 

Em resposta a Mike B , eu prefiro usar ‘class’ como, dentro de um template, ‘typename’ tem um significado sobrecarregado, mas ‘class’ não. Tome este exemplo de tipo de inteiro marcado:

 template  class smart_integer { public: typedef integer_traits traits; IntegerType operator+=(IntegerType value){ typedef typename traits::larger_integer_t larger_t; larger_t interm = larger_t(myValue) + larger_t(value); if(interm > traits::max() || interm < traits::min()) throw overflow(); myValue = IntegerType(interm); } } 

larger_integer_t é um nome dependente, portanto, requer que o 'typename' o anteceda para que o analisador reconheça que o larger_integer_t é um tipo. class , por outro lado, não tem tal significado sobrecarregado.

Isso ... ou eu sou apenas preguiçoso no coração. Eu digito 'class' com muito mais frequência do que 'typename' e, portanto, acho muito mais fácil digitar. Ou pode ser um sinal de que escrevo muito código OO.

Apenas pura história. Citação de Stan Lippman :

A razão para as duas palavras-chave é histórica. Na especificação do modelo original, o Stroustrup reutilizou a palavra-chave class existente para especificar um parâmetro de tipo, em vez de introduzir uma nova palavra-chave que poderia, é claro, quebrar programas existentes. Não foi uma nova palavra-chave que não foi considerada – apenas que não foi considerada necessária devido à sua potencial ruptura. E até o padrão ISO-C ++, essa era a única maneira de declarar um parâmetro de tipo.

Mas deve-se usar typename ao invés de class ! Veja o link para mais informações, mas pense no seguinte código:

 template  class Demonstration { public: void method() { T::A *aObj; // oops ... }; 

Não importa, mas a class faz parecer que o T só pode ser uma class, embora possa ser qualquer tipo. Então typename é mais preciso. Por outro lado, a maioria das pessoas usa a class, o que provavelmente é mais fácil de ler em geral.

Tanto quanto eu sei, não importa qual você usa. Eles são equivalentes aos olhos do compilador. Use o que você preferir. Eu normalmente uso aula.

Estendendo o comentário de DarenW.

Uma vez que typename e class não são aceitos como muito diferentes, pode ser válido para ser estrito em seu uso. Use class somente se for realmente uma class e typename quando for um tipo básico, como char .

Esses tipos também são aceitos em vez de typename

template < char myc = ‘/’>

o que seria até mesmo superior ao typename ou class.

Pense em “clareza” ou inteligibilidade para outras pessoas. E realmente considere que softwares / scripts de terceiros podem tentar usar o código / informação para adivinhar o que está acontecendo com o modelo (considere swig).