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 ++?

Foi útil?

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:

exemplo metatrace

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.

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

BOOST_FOREACH

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!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top