Genéricos e modelos (Visual C++)
Os genéricos e modelos são os dois recursos de linguagem que oferecem suporte para tipos parametrizados.No entanto, eles são diferentes e têm usos diferentes.Este tópico fornece uma visão geral das muitas diferenças.
Para obter mais informações, consulte Tempo de Execução do Windows e Modelos Gerenciados (Extensões de Componentes C++) e Visão geral de modelos.
Comparando modelos e genéricos
Principais diferenças entre genéricos e modelos C++:
Os genéricos são genéricos, até que os tipos são substituídos por eles em tempo de execução.Modelos são especializados em tempo de compilar para que não estejam ainda com parâmetros de tipos em tempo de execução
Especificamente, o Common Language Runtime suporta genéricos em MSIL.Como o tempo de execução sabe sobre genéricos, tipos específicos podem ser substituídos por tipos genéricos, ao fazer referência a um assembly que contém um tipo genérico.Modelos, em contraste, resolver em comuns tipos em tempo de compilar e os tipos de resultantes não podem ser especializados em outros assemblies.
Os genéricos especializada em dois assemblies diferentes com o mesmo tipo argumentos são do mesmo tipo.Modelos especializada em dois assemblies diferentes com o mesmo tipo de argumentos são considerados pelo tempo de execução tipos diferentes.
Os genéricos são gerados como uma única parte do código executável que é usado para todos os argumentos de tipo de referência (isso não é válido para os tipos de valor, que têm uma implementação exclusiva por tipo de valor).compilador JITsabe sobre genéricos e é capaz de otimizar o código para os tipos de referência ou valor que são usados como argumentos de tipo. Modelos geram código de tempo de execução de separado para cada especialização.
Os genéricos não permitem parâmetros de tipo não modelo , como template <int i> C {}.Os modelos permitem a elas.
Os genéricos não permitem a especialização explícita (isto é, uma implementação personalizada de um modelo para um tipo específico).Modelos de fazem.
Os genéricos não permitem a especialização parcial (uma implementação personalizada para um subconjunto dos argumentos de tipo).Modelos de fazem.
Os genéricos não permitem o tipo de parâmetro a ser usado como a classe base para o tipo genérico.Modelos de fazem.
Modelos suportam (por exemplo, o modelo- parâmetros demodelotemplate<template<class T> class X> class MyClass), mas não genéricos .
A combinação de modelos e genéricos
- A diferença básica em genéricos tem implicações para a criação de aplicativos que combinam os modelos e genéricos.Por exemplo, suponha que você tem umaclasse de modeloque você deseja criar um wrapper genérica para expor esse modelo para outros idiomas como um genérico. Você não pode ter o genérico têm um parâmetro de tipo que ele então passa embora para o modelo, pois o modelo precisa ter esse tipo de parâmetro em tempo de compilar , mas a genérica não resolver o tipo de parâmetro até que o tempo de execução.Aninhar um modelo dentro de um genérico não funcionará porque não há nenhuma forma de expandir os modelos em tempo de compilar para tipos genéricos arbitrários que pode ser instanciada em tempo de execução.
Exemplo
Descrição
O exemplo a seguir mostra um exemplo simples de usar modelos e genéricos juntos.Neste exemplo, aclasse de modelopassa seu parâmetro através do tipo genérico. O inverso não é possível.
Este idioma pode ser usado quando você deseja compilação em uma API genérica existente com o código de modelo que seja local para um assemblydo Visual C++, ou quando você precisa adicionar uma camada extra de parametrização para um tipo genérico, para aproveitar as vantagens de determinados recursos dos modelos genéricosnão oferece suportados.
Código
// templates_and_generics.cpp
// compile with: /clr
using namespace System;
generic <class ItemType>
ref class MyGeneric {
ItemType m_item;
public:
MyGeneric(ItemType item) : m_item(item) {}
void F() {
Console::WriteLine("F");
}
};
template <class T>
public ref class MyRef {
MyGeneric<T>^ ig;
public:
MyRef(T t) {
ig = gcnew MyGeneric<T>(t);
ig->F();
}
};
int main() {
// instantiate the template
MyRef<int>^ mref = gcnew MyRef<int>(11);
}
Saída
F