generic - template class t c++ example
Default template parameter partial specialization (3)
Por favor, explíqueme por qué la siguiente pieza de código cumple y funciona perfectamente. Estoy muy confundido.
#include<iostream>
template<class A = int, class B=double>
class Base
{};
template<class B>
class Base <int, B>
{
public:
Base()
{
std::cout<<"it works!!!!!/n";
}
};
int main()
{
Base<> base; // it prints "it works!!!!!"
return 0;
}
¿No debería caer en la forma generalizada de la clase de plantilla Base?
Cuando escribes Base<> base;
el compilador intentará averiguar si la creación de instancias de la clase Base<>
es posible o no, si es posible que el código funcione bien. En este caso, es posible debido al argumento de plantilla predeterminado de Base porque el compilador sabe si usted, si escribe Base<>
, necesita crear un objeto de Base<int,double>
. es decir: debido a:
template<class A = int, class B=double>
class Base
{};
Entonces el código funciona bien.
El argumento predeterminado se aplica a la especialización, y, de hecho, una especialización debe aceptar (por así decirlo) los argumentos predeterminados de la plantilla base. Intentando especificar un valor predeterminado en la especialización:
template<class A = int, class B=double>
class Base
{};
template<class B=char>
// ...
... es un error
Del mismo modo, si cambiamos la especialización para que su especialización sea para un tipo diferente al predeterminado provisto por la plantilla base:
template<class A = int, class B=double>
class Base
{};
template<class B>
class Base <char, B>
... entonces se elegirá la plantilla base.
Entonces, lo que está sucediendo es esto: primero se eligen los tipos para los argumentos de la plantilla. En este caso (ningún tipo especificado en la instanciación), ambos tipos se basan en los argumentos de plantilla predeterminados especificados en la plantilla base.
Luego (como un paso básicamente separado) lleva a cabo un análogo de resolución de sobrecarga en todas las plantillas que se ajustan a esos tipos de argumentos. Como es habitual para la resolución de sobrecarga, se prefiere un tipo que se especifica explícitamente sobre uno que se especifica implícitamente, por lo que su especialización (que especificó int
explícitamente) es preferible a la plantilla base (que se especifica int
implícitamente).
template<class A = int, class B=double>
class Base
{};
Aquí los valores predeterminados / inicialización para A y B se han declarado respectivamente como int y doble.
template<class B>
class Base <int, B>
Aquí en las definiciones de clases, el primer argumento es algo así como un valor constante (aquí int; ¿por qué declarar de esta manera simplemente hacer las cosas complejas? Mejor eliminar el primer argumento de plantilla) y el segundo argumento de plantilla es B cuyo valor predeterminado es ''doble''.
Base<> base;
Cuando creas el objeto de la clase. Aunque no especifica los argumentos de la plantilla, el compilador toma los valores por defecto de los argumentos (A y B) que son ''int'' y ''double'' y el código se ejecuta sin ningún error ni advertencia.
Vea lo que ocurre cuando crea el objeto como:
Base<float,char> b;
o Base<char,char> b;