Post on 01-Jan-2016
description
Metaprogramação Estática
André Knabben
Pricilla Padaratz
Metaprogramação
Envolve escrever programas relacionados pela meta-relação relação de “ser sobre”
Programas que manipulam e geram outros programas
Metaprogramação Estática
Metaprogramas estáticos são executados antes do código que eles manipulam em tempo de compilação
Compiladores e pré-processadores Open Compiler tornar a metaprogramação
mais acessível
Templates
Metaprogramação em C++ Classes e funções que operam com números
e/ou tipos como dados Recursão de templates Especialização de templates
Templates
Compilador executa operações codificam-se dados como tipos usa-se o compilador para interpretar metaprogramas
Templates Reutilizar código fonte X
Herança e Composição Reutilizar código de objetos
Classes
Implementação de templates genéricos com paramêtros de tipo
Compilador gera a classe de acordo com o tipo
Por exemplo:template<class T>
class Fila { ...}
Fila<int>, Fila<Clientes>, etc.
Funções
Implementação de funções genéricas que podem ser usadas com tipos arbitrários
Compilador gera código de acordo com o tipo Rotinas de busca, rotinas de sort
Exemplo:template<class T>T max(T a, T b){
return a > b ? a : b;}
Especialização
É possível definir especializações de templates para tipos específicos
Especialização de classes e de funções
Exemplo:template<class T>class Lista { ... }
template<>class Lista<char> { ... }
O template Lista<char> é usado para definir Listas de caracteres; outras Listas serão geradas a partir do template base Lista<class T>
Especialização Parcial
Usada para gerar especializações de templates onde alguns parâmetros permanecem fixos e outros variam
Não são suportados por todos os compiladores– Suportado pelos GCC mais recentes– Suportado pelo compilador da Intel– Não suportado pelo Visual C++ 6.0
Exemplo
template<bool cond, class ThenType, class ElseType>struct IF {
typedef ThenType RET;};template<class ThenType, class ElseType>struct IF<false, ThenType, ElseType>{
typedef ElseType RET;};
Meios de prover informação sobre tipos
Definir um traits template para o tipo:
Traits templates provêem informações sobre outros tipos
Colocar a informação diretamente como parte do tipo (member traits)
Criar uma classe com os traits (trait classes)
Promoção de tipos
Traits podem ser usados para promover tipos– X = Y + Z: resultado da operação + assume tipo de
acordo com algum critério (int + double => double)
Exemplo de uso: classes matemáticas
Princípios de Codificação
Typedef: atribuição para tipo Enum: atribuição para valor Recursão de template: loop Operador ? : e especialização de template:
condicional
Uso de namespace e private/protected para ocultar operações intermediárias
Instantiation/Lazyness
Compilador instancia templates apenas quando necessário
Ex: template <class T> struct X { /*code */} typedef X<int> X_INT; // não X_INT *x; // não X_INT x; // sim
Instantiation/Lazyness
template <class T_>class Uma { typedef T_ Tipo; };
template <class T_>class Outra { typedef T_ Tipo; };
typedef IF<cond, Uma<int>::Tipo, Outra<bool>::Tipo>::RET TIPO1; // ruim
typedef IF<cond, Uma<int>, Outra<bool> >::RET::Tipo TIPO1; // bom
template class vector<int>; // instanciação explícita
Outros templates como parâmetro
template <class T>struct Base { /* code */ }
template < class ElementType, template<class>class ListType >struct ListUser{ typedef ListType<Proxy<ElementType> > MyList;};
Alternativa: Criar estrutura para passar um parâmetro template
struct UsarTipo1 { template <class Internal> struct UseType { typedef Tipo1<Internal> RET; }; };
template <class ListTypeTemplate>struct ListUser { typedef TipoTemplate::UseType<Proxy<int> >::RET
MyList; };
Expression Templates
Servem para otimizar/restringir o uso de expressões usando redefinição de operadores
M1 = (M2 + M3 + M4) * M5; Permite:
– Armazenar as operações a serem executadas e otimizar a expressão (incluindo as mesmas otimizações que o compilador faria);
– Adicionar restrições adicionais do domínio tratado.
Exemplo: Expression Templates
(4 * 3) + 10
Modelagem Lista
Modelagem Lista
Código
Compilando com o G++
In file included from lista.h:6, from lista.cpp:1: smp_inherit.h:39: parse error before `;' token
template <class ChildType> struct UseType { typedef typename Type<ChildType> RET; };
Problemas
Ferramentas/compiladores não estão preparadas para o uso intensivo de templates– Não há como verificar como o compilador está
instanciando os templates– Problemas com o debug– Mensagens de erro ruins– Recursos de autocompletar não funcionam
Ex. Mensagem do compilador
Z:\SMP\teste\src\main.cpp(66): error: no suitable constructor exists to convert from "LinkedNode<GenerateSubClass<int, LinkedNode, SubTypeList<DoublyLinkedNode, SubTypeList<LengthNode, EndTypeList>>>>::NodeType *" to "DoublyLinkedNode<GenerateSubCla
ssInternals::GenerateSubClass_<GenerateSubClassInternals::GenerateSubClass_<GenerateSubClass<int, LinkedNode, SubTypeList<DoublyLinkedNode, SubTypeList<LengthNode, EndTypeList>>>::Env={int}, LinkedNode<GenerateSubClass<int, LinkedNode,
SubTypeList<DoublyLinkedNode, SubTypeList<LengthNode, EndTypeList>>>>, SubTypeList<DoublyLinkedNode, SubTypeList<LengthNode, EndTypeList>>>::Env={GenerateSubClass<int, LinkedNode, SubTypeList<DoublyLinkedNode, SubTypeList<LengthNode, EndTy
peList>>>::Env={int}}, LinkedNode<GenerateSubClass<int, LinkedNode, SubTypeList<DoublyLinkedNode, SubTypeList<LengthNode, EndTypeList>>>>, SubTypeList<DoublyLinkedNode, SubTypeList<LengthNode, EndTypeList>>::Tail>::RET>"
*last = (x.next)->next->next;
Bibliografia
CZARNECKI, K., EISENECKER, U. Generative Programming: Methods, Techniques and Applications. Addison-Wesley, 2000.
C++ Templates Tutorial:http://babbage.cs.qc.edu/STL_Docs/templates.htm