Quais são os exemplos mais legais de metaprogramming que você já viu em C ++? [fechadas]
-
04-07-2019 - |
Pergunta
Quais são os exemplos mais legais de metaprogramming que você já viu em C ++?
Quais são alguns usos práticos de metaprogramming que você já viu em C ++?
Solução
Pessoalmente, acho Boost.Spirit é um exemplo incrível de meta-programação. É um gerador de analisador completa que lhe permite expressar gramáticas usando a sintaxe C ++.
Outras dicas
O uso mais prático de programação meta está virando um erro de execução em um erro de tempo de compilação.
Exemplo: Vamos chamar a IFoo interface. Um dos meus programas lidou com um objeto COM que tinha vários caminhos para IFoo (muito complicada hierarquia de herança). Infelizmente, a implementação de objeto COM subjacente não sabia que eles tinham vários caminhos para IFoo. Eles assumiram que era sempre o mais esquerdo. Então, dentro de seu código, o seguinte padrão era muito comum
void SomeMethod(IFoo* pFoo) {
CFooImpl *p = (CFooImpl)pFoo;
}
O segundo IFoo que causou o ponteiro "p" resultante para ser completamente inválido (herança múltipla é perigoso).
A solução a longo prazo era ter o proprietário do objeto COM corrigir esse problema. de curto prazo que eu precisava ter certeza de que eu sempre voltava a IFoo correta. Eu poderia garantir que eu tinha o IFoo apropriado usando um QI e evitando quaisquer casts implícitas a IFoo. Então, eu criei um novo CComPtr <> implementação e adicionaram a seguinte substituição para o método igual.
template <typename T>
CComPtr<T>& operator=(const T* pT) {
// CComPTr Assign logic
}
template <>
CComPtr<IFoo> operator=<IFoo>(const IFoo* pT) {
COMPILE_ERROR();
}
Esta rapidamente revelado cada lugar que eu fundido implicitamente IFoo.
Não de uso prático (exceto talvez para o teste do compilador), mas metatrace é um Whitted-Style (ou seja recursiva e determinista) tracer raio que gera imagens como aquelas em tempo de compilação:
Algumas peças mais complexas do código pode ser visto em fixp.hh , que tem uma implementação de ponto fixo sqrt usando o Heron método, ou sphere.hh que mostra o raio / esfera-intersecção cálculo.
Blitz ++ faz algumas coisas impressionantes com modelos (por exemplo, uma única linha legível do código pode ser transformou-se em um conjunto de laços sobre uma matriz multidimensional, optimizada automaticamente para a melhor ordem de passagem).
Coolest exemplo metaprogramming: enganando o compilador para computar uma lista de números primos. Não é muito prático, mas impressionante.
Um uso prático é tempo de compilação assert declarações, ou seja, causando um erro de compilação se uma condição booleana não se sustenta.
Loki escrito por Andrei Alexandrescu
Eu teria que dizer Boost.Lambda, Boost.Function e Boost.Bind e da maneira que todos eles funcionam perfeitamente em conjunto. Eles fornecem uma interface realmente liso e fazer programação funcional tão fácil quanto possível em um idioma que não foi realmente construído para ele.
luabind é um muito legal exemplo prático, um bom DSL ligação bom para a ligação classes C ++ para Lua
afirmação estáticos (aumenta a versão aqui )
(Nota: suporte interno para se introduz-intervalo com base em loops e afirmações estáticos em C ++ 11)
Eu fiz uma pergunta não muito tempo atrás: C ++ Runtime conhecimento das classes ea resposta I got de usuário StackOverflow "Denice" era uma URL para um site meatspace:. C ++ runtime registro da classe
Eu acho que é uma maneira muito legal de usar modelos e objetos instanciar que são todos derivados de uma classe base, de modo que quando eu tiver 10 arquivos C ++, todos eles podem basta adicionar o AUTO_REGISTER_BASE () na parte inferior, e quando tudo é feito e ligada, apenas as classes / arquivos que fizeram seria registrado, por isso em tempo de execução, você pode alternar entre as diferentes classes que estão disponíveis, e aqueles que não estão disponíveis não são registrados e, portanto, não pode acidentalmente ser chamado .
Existem muitas maneiras diferentes OS dependentes para fazer a notificação de eventos (select (), kqueue (), / dev / epoll, Solaris tem a sua própria coisa, poll ()), e eu precisava de uma maneira de ter toda a classe existem arquivos no diretório, mas dependendo de qual sistema operacional o Makefile foi executado, seria apenas compilar certas pessoas. Eu precisava de uma maneira de saber em tempo de execução quais estavam disponíveis, e ter um caminho para o programador usando a biblioteca para selecionar sua preferência, no entanto, se ele não estava disponível para apenas usar o que fez o sentido mais lógico para a plataforma (cada um deles têm pesos atribuídos a eles).
O código acima me ajudou a alcançar este objetivo, com algumas modificações pesadas, mas isso me ajudou nada-a-menos!