c++ - programacion - ¿Cómo se crea una instancia de una plantilla?
plantillas con arreglos en c++ (2)
Es un ejercicio de C ++ Primer 5th Edition :
Ejercicio 16.27: Para cada afirmación etiquetada, explique qué suceden las instancias, si las hay. Si se crea una instancia de una plantilla, explique por qué; Si no, explica por qué no. P.677
template <typename T> class Stack { };
void f1(Stack<char>); // (a)
class Exercise {
Stack<double> &rsd; // (b)
Stack<int> si; // (c)
};
int main() {
Stack<char> *sc; // (d)
f1(*sc); // (e)
int iObj = sizeof(Stack< string >); // (f)
}
A continuación es lo que he intentado:
(a) La Stack<char>
está instanciada, pero ningún miembro de la misma está instanciado.
(b) La Stack<double>
está instanciada, pero ningún miembro de la misma está instanciado.
(c) Se crea una instancia de la Stack<int>
y su constructor predeterminado.
(d) (e) totalmente sin idea ...
(f) La Stack< string >
está instanciada, pero ningún miembro de la misma está instanciado.
Estoy en lo cierto? ¿Alguien puede decirme cómo este código es instanciado?
En su caso específico, una declaración no significa una instanciación
#include <iostream>
using namespace std;
template <typename T> class Stack {
typedef typename T::ThisDoesntExist StaticAssert; // T::NotExisting doesn''t exist at all!
};
void f1(Stack<char>); // No instantiation, compiles
class Exercise {
Stack<double> &rsd; // No instantiation, compiles (references don''t need instantiation, are similar to pointers in this)
Stack<int> si; // Instantiation! Doesn''t compile!!
};
int main(){
Stack<char> *sc; // No Instantiation, this compiles successfully since a pointer doesn''t need instantiation
f1(*sc); // Instantiation of Stack<char>! Doesn''t compile!!
int iObj = sizeof(Stack< std::string >); // Instantiation of Stack<std::string>, doesn''t compile!!
}
note el puntero / material de referencia: no requieren creación de instancias ya que en realidad no se asignan datos (un puntero es solo unos pocos bytes para contener la dirección, no es necesario tener todos los datos almacenados ... mire el lenguaje de los pánppls ).
Solo cuando las cosas se asignan , la plantilla debe resolverse por completo (y eso ocurre en tiempo de compilación, por eso es que generalmente necesitan declaración y definición ... aún no hay fase de enlace)
Respecto a e y d citaré el estándar 14.7.1.
A menos que una especialización de plantilla de función haya sido explícitamente instanciada o explícitamente especializada, la especialización de plantilla de función se crea implícitamente cuando se hace referencia a la especialización en un contexto que requiere que exista una definición de función. A menos que una llamada sea a una especialidad explícita de la plantilla de función o una función miembro de una plantilla de clase explícitamente especializada, un argumento predeterminado para una plantilla de función o una función miembro de una plantilla de clase se crea una instancia implícita cuando se llama a la función en un contexto que requiere El valor del argumento por defecto.
Ejemplo también de la norma.
template<class T> struct Z {
void f();
void g();
};
void h()
{
Z<int> a; // instantiation of class Z<int> required
Z<char>* p; // instantiation of class Z<char> not required
Z<double>* q; // instantiation of class Z<double> not required
a.f(); // instantiation of Z<int>::f() required
p->g(); // instantiation of class Z<char> required, and instantiation of Z<char>::g() required
}
Esto significa que no hay instanciación en d. Mientras que se creará una instancia en e si esa función realmente necesita llamar a una función de ese tipo (podría ser un constructor de copia o cualquier otra función llamada dentro de la función).