Estou tentando entender o que é metaprogramação geral e o que é em C ++ em particular. Se eu procurar a metaprogramação em c ++, recebo tutoriais de metaprogramação de modelo (TMP), mas não há explicação para se ela apenas categoriza um uso específico de modelos ou todos os usos de modelos.
Minha pergunta é se todos os usos de modelos em C ++ são categorizados como metaprogramação. Uma explicação de por que é ou não é também seria útil. Obrigado.
Respostas:
Não.
Nem todos os usos de modelos, em C ++, são metaprogramadores.
Obviamente, é uma questão de definições, mas, em C ++, "metaprogramação" é sinônimo de "computação em tempo de compilação".
Portanto, com modelos, fazemos metaprogramação (especificamente metaprogramação de modelo), mas nem todos os usos de modelos são metaprogramação.
Um contra-exemplo simples
O anterior
printKeyVal()
é uma função de modelo que imprime, na saída padrão (portanto, em tempo de execução, não em tempo de compilação), alguns valores genéricos.Ele não pode ser executado em tempo de compilação, portanto é "modelo", mas não é "metaprogramador".
Mais em geral:
std::vector
é uma classe de modelo que usa alocação de memória. E a alocação de memória (até C ++ 17; talvez no futuro possa ser diferente) não pode ser usada no código em tempo de compilação.Portanto
std::vector
(ao contráriostd::array
disso, ter um tamanho fixo, não usa alocação de memória) é um recurso de modelo que não pode ser usado (quando o uso envolve a instanciação de umstd::vector
objeto) para metaprogramação.fonte
printKeyVal
é definido durante o tempo de compilação, de acordo com os argumentos do modeloO que é TMP em C ++?
A metaprogramação de modelos (TMP) em C ++ é uma técnica para expressar e executar algoritmos arbitrários em tempo de compilação usando modelos C ++. Geralmente é habilitado pelo uso da especialização de modelo para emular ramificações condicionais e a definição de modelo recursivo para emular loops. O exemplo mais conhecido é uma computação fatorial em tempo de compilação:
que usa as duas técnicas mencionadas acima.
Muito mais comum, no entanto, é o uso de TMP para detecção e transformação de tipos, em vez de computação numérica real, por exemplo, um
std::is_pointer
utilitário padrão ( fonte ):A maioria dos utilitários fornecidos pelo cabeçalho type_traits padrão é implementada usando técnicas TMP.
Dado que os algoritmos TMP são expressas usando definições de tipo, vale a pena mencionar que TMP é uma forma de programação declarativa em que a lógica do cálculo é expresso sem o uso de demonstrações de fluxo de controle explícitas (
if
,else
,for
, etc ...).Todo o uso de modelos C ++ é uma metaprogramação?
A resposta curta é: Não. Se os modelos não são usados para expressar um algoritmo em tempo de compilação, não é uma metaprogramação, é uma programação genérica .
O objectivo principal para a introdução de modelos em C ++ foi para permitir a programação genérico, que é o de permitir reutilizar os mesmos algoritmos (
find
,copy
,sort
, etc ...) e as estruturas de dados (vector
,list
,map
, etc ...) para quaisquer tipos, incluindo pelo utilizador definidos, que satisfazem certos requisitos.De fato, o TMP em C ++ foi descoberto por acidente e não era o uso pretendido de modelos.
Em resumo: A metaprogramação de modelos em C ++ é o uso de modelos para expressar um algoritmo em tempo de compilação, a maioria (todos?) Dos outros usos de modelos C ++ é uma forma de programação genérica.
fonte
Você ainda não disse o que entende por metaprogramação em geral , para que suas respostas não tenham um ponto de partida comum.
Vou assumir que a definição da Wikipedia é boa o suficiente para isso:
O C ++ geralmente não permite código auto-modificável, então estou ignorando isso. Também estou optando por não contar o pré-processador, pois a substituição de texto no (ou provavelmente antes) tempo de compilação não é o mesmo que operar na semântica do programa.
Não não é.
Considere, para referência:
que é vagamente a maneira de escrever uma função genérica (
max
independente de tipo) sem usar modelos. Eu já disse que não conto o pré-processador como metaprogramação, mas, em qualquer caso, ele sempre produz código idêntico sempre que é usado.Ele simplesmente delega a análise desse código e a preocupação com os tipos e se
a>b
está definido para o compilador, em uma fase posterior da tradução . Nada aqui opera em tempo de compilação para produzir código resultante diferente dependendo de ... qualquer coisa. Nada, em tempo de compilação, é calculado.Agora, podemos comparar a versão do modelo:
Isso não realiza simplesmente uma substituição textual. O processo de instanciação é mais complexo, regras de sobrecarga de nomes e sobrecargas podem ser consideradas e, em certo sentido, instâncias diferentes podem não ser textualmente equivalentes (por exemplo, um pode ser usado
bool ::operator< (T,T)
e umbool T::operator<(T const&)
ou o que for).No entanto, o significado de cada instanciação é o mesmo (assumindo definições compatíveis
operator<
para tipos diferentes etc.) e nada foi computado no tempo de compilação, exceto o processo (mecânico) usual do compilador de resolver tipos e nomes e assim por diante.Como um aparte, definitivamente não é suficiente que seu programa contenha instruções para o compilador dizer o que fazer , porque é isso que é toda a programação.
Agora, existem casos marginais como
que faz mover um cálculo de tempo de compilação (e neste caso, um não-encerramento uma vez que não pode ser incomodado para escrever o caso terminal), mas sem dúvida são não metaprogramming.
Mesmo que a definição da Wikipedia mencionasse mover cálculos para compilar tempo, isso é apenas um cálculo de valor - não está tomando uma decisão em tempo de compilação sobre a estrutura ou semântica do seu código.
fonte
Ao escrever funções C ++ com modelos, você está escrevendo "instruções" para o compilador dizer o que fazer ao encontrar chamadas da função. Nesse sentido, você não está escrevendo código diretamente, portanto, chamamos de metaprogramação.
Então, sim, todo código C ++ envolvendo modelos é considerado metaprogramação
Observe que apenas as partes que definem funções ou classes de modelos são metaprogramação. Funções e classes regulares são categorizadas como C ++!
fonte
std::vector
, instruo um compilador a produzir um programa (por isso é meta), mas a instrução em si dificilmente é um programa. A maioria das pessoas não considera o uso de macros "metaprogramação".