Ensayo de C ++, la segunda pequeña nota sobre la plantilla 16.1.3 parámetros de la plantilla

16.1.3 Parámetros de plantilla

Muchas veces definimos el nombre del parámetro como T, pero de hecho podemos usar cualquier nombre

como

template <typename DATA>using partNo = BlobA<DATA>;

Parámetros de plantilla y reglas de alcance. El rango utilizable de un nombre de parámetro de plantilla es después de su declaración y antes del final de la declaración o definición de la plantilla. Como cualquier otro nombre, los parámetros de la plantilla ocultan el mismo nombre declarado en el ámbito externo. Sin embargo, como en la mayoría de los demás contextos, los nombres de los parámetros de plantilla no se pueden reutilizar dentro de las plantillas:

typedef double A;
template <typename A,typename B>void f(A a,B b)
{
    A tmp = a;
    double B;//错误重复声明模板参数B
}

Debido a que el nombre de tipo B de B se ha declarado anteriormente, el tipo de B se ha declarado a continuación. También
tenga en cuenta que el tipo de temperatura no es doble, es el tipo de parámetro real de la plantilla

Declaración de plantilla:

La declaración de plantilla debe contener parámetros de plantilla

template <typename T> int compare(const T&, const T&);
template <typename T> class Blob;

Al igual que con las funciones, el nombre de la plantilla en la declaración no tiene que ser el mismo que cuando se definió

template <typename T> T calc(const T&,const T&);
template <typename U> U calc(const U&,const U&);

Por ejemplo, estas dos funciones de plantilla son en realidad las mismas, por lo que habrá definiciones duplicadas.

Usar miembros de tipo de clase

Por ejemplo, podemos usar string :: size_type, conocemos el tipo de string, pero para la plantilla T :: mem, no sabemos el tipo de T

De forma predeterminada, el lenguaje C ++ asume que el nombre al que se accede a través del operador de alcance no es un tipo. Entonces, si queremos usar un miembro de tipo de un parámetro de tipo de plantilla, debemos decirle explícitamente al compilador que el nombre es un tipo. Logramos esto usando typename.

template <typename T>
typename T::value_type top(const T&c)
{
    if(!c.empty())
        return c.back();
    else
        return typename T::value_type();
}

Nuestra función superior espera un argumento de tipo contenedor. Utiliza typename para indicar el tipo de retorno y genera un elemento inicializado con valor para devolver al llamador cuando no hay ningún elemento en c.

Luego miramos el código

int main()
{
    int b;
    std::vector<int> vec;
    top(vec);
//    std::cout<<partNo<int>::count()<<std::endl;
    return 0;
}

Si se pasa vec, es correcto. Si se pasa a porque es un int, es incorrecto. Todo esto es gracias al hecho de que informamos al compilador con anticipación.

Supongo que te gusta

Origin blog.csdn.net/qq_32783703/article/details/104601574
Recomendado
Clasificación