O compilador gerará código para cada instanciação de modelo quando você usar um modelo durante a etapa de compilação. No processo de compilação e vinculação, os arquivos .cpp são convertidos em objeto puro ou código de máquina, que contém referências ou símbolos indefinidos, porque os arquivos .h incluídos no seu main.cpp ainda não têm implementação. Eles estão prontos para serem vinculados a outro arquivo de objeto que define uma implementação para o seu modelo e, portanto, você tem um executável a.out completo.
No entanto, como os modelos precisam ser processados na etapa de compilação para gerar código para cada instanciação de modelo que você definir, simplesmente compilar um modelo separado do arquivo de cabeçalho não funcionará porque eles sempre andam de mãos dadas, pelo mesmo motivo que cada instanciação de modelo é uma classe totalmente nova literalmente. Em uma classe regular, é possível separar. Hepp. Porque. H é um blueprint dessa classe e o. Cpp é a implementação bruta, para que todos os arquivos de implementação possam ser compilados e vinculados regularmente, no entanto, usando os modelos. H é um blueprint de como a classe não deve ter a aparência do objeto, o que significa que um arquivo .cpp de modelo não é uma implementação regular bruta de uma classe; é simplesmente um modelo para uma classe; portanto, qualquer implementação de um arquivo de modelo .h pode '
Portanto, os modelos nunca são compilados separadamente e são compilados apenas onde você tiver uma instanciação concreta em outro arquivo de origem. No entanto, a instanciação concreta precisa conhecer a implementação do arquivo de modelo, porque simplesmente modificar otypename T
usar um tipo concreto no arquivo .h não fará o trabalho porque o que .cpp está lá para vincular, não consigo encontrá-lo mais tarde porque lembre-se de que os modelos são abstratos e não podem ser compilados, então sou forçado para fornecer a implementação agora, para que eu saiba o que compilar e vincular, e agora que tenho a implementação, ela será vinculada ao arquivo de origem. Basicamente, no momento em que instanciamos um modelo, preciso criar uma classe totalmente nova, e não posso fazer isso se não souber como deve ser essa classe ao usar o tipo que forneço, a menos que notifique o compilador de a implementação do modelo, agora o compilador pode substituir T
pelo meu tipo e criar uma classe concreta que está pronta para ser compilada e vinculada.
Resumindo, modelos são modelos para a aparência das classes, classes são modelos para a aparência de um objeto. Não consigo compilar modelos separados de sua instanciação concreta porque o compilador compila apenas tipos concretos, ou seja, modelos pelo menos em C ++, é pura abstração de linguagem. Temos que des-abstrair modelos, por assim dizer, e fazemos isso dando a eles um tipo concreto para lidar, para que nossa abstração de modelo possa se transformar em um arquivo de classe regular e, por sua vez, possa ser compilado normalmente. A separação do arquivo .h do modelo e do arquivo .cpp do modelo não faz sentido. Não faz sentido, porque a separação de .cpp e .h é apenas onde os .cpp podem ser compilados individualmente e vinculados individualmente, com modelos, pois não podemos compilá-los separadamente, porque os modelos são uma abstração,
O significado de typename T
get é substituído durante a etapa de compilação, e não na etapa de vinculação, por isso, se eu tentar compilar um modelo sem T
ser substituído como um tipo de valor concreto que é completamente sem sentido para o compilador e, como resultado, o código do objeto não pode ser criado porque não sabe o que T
é.
É tecnicamente possível criar algum tipo de funcionalidade que salvará o arquivo template.cpp e alterará os tipos quando os encontrar em outras fontes. Acho que o padrão possui uma palavra-chave export
que permite colocar modelos em um arquivo separado. arquivo cpp, mas não muitos compiladores realmente implementam isso.
Apenas uma observação, ao fazer especializações para uma classe de modelo, você pode separar o cabeçalho da implementação, porque uma especialização por definição significa que eu sou especializado em um tipo concreto que pode ser compilado e vinculado individualmente.