Capítulo 3 Parámetros de plantilla sin tipo: 3.3 Restricciones en los parámetros de plantilla sin tipo

3.3 Restricciones para los parámetros de plantilla sin tipo

3.3 Restricciones en los parámetros de plantilla sin tipo

 

Tenga en cuenta que los parámetros de plantilla que no son de tipo tienen algunas restricciones. En general, pueden

sean solo valores integrales constantes (incluidas las enumeraciones), punteros a objetos / funciones / miembros, referencias de valor a objetos o funciones, o std :: nullptr_t (el tipo de nullptr).

Tenga en cuenta que los parámetros de plantilla que no son de tipo son limitados. En términos generales, solo pueden ser enteros constantes (incluidas las enumeraciones), punteros a objetos / funciones / miembros, referencias de valor a objetos o funciones, o std :: nullptr_t (tipo de nullptr).

 

Los números de punto flotante y los objetos de tipo de clase no están permitidos como plantilla sin tipo

parámetros:

Los objetos de clase y de punto flotante no están permitidos como parámetros de plantilla que no son de tipo:

template < double VAT> // ERROR: los números de coma flotante no se pueden usar como parámetros de plantilla que no son de tipo 
double process ( double v) // pero se pueden usar como parámetros de plantilla 
{
     return v * VAT; 
} 
 
template <std :: string name> // ERROR: class El tipo no se puede utilizar como una 
clase de parámetro de plantilla que no es de tipo MyClass { // permitido como parámetros de plantilla 
    ... 
};

Al pasar argumentos de plantilla a punteros o referencias, los objetos no deben ser literales de cadena, temporales o miembros de datos y otros subobjetos. Debido a que estas restricciones se relajaron con todas y cada una de las versiones de C ++ anteriores a C ++ 17, se aplican restricciones adicionales:

Al pasar punteros o referencias a argumentos de plantilla, los objetos no pueden ser literales de cadena, objetos temporales o miembros de datos y otros subobjetos. Debido a que cada versión de C ++ anterior a C ++ 17 relaja estas restricciones, se aplican restricciones adicionales a:

• En C ++ 11, los objetos también tenían que tener un enlace externo.

  En C ++ 11, los objetos también deben tener enlaces externos.

• En C ++ 14, los objetos también tenían que tener un enlace externo o interno.

  En C ++ 14, los objetos también deben estar vinculados externa o internamente.

Por lo tanto, lo siguiente no es posible:

Por lo tanto, lo siguiente no es posible:

template < char  const * name>
 class MyClass { 
}; 

MyClass < " hello " > x; // ERROR: los literales de cadena no están permitidos ("hello")

Sin embargo, existen soluciones alternativas (nuevamente, según la versión de C ++):

Sin embargo, hay algunas soluciones alternativas (nuevamente dependientes de la versión C ++):

extern  char  const s03 [] = " hi " ; // enlace externo 
char  const s11 [] = " hi " ; // enlace interno 

int main () 
{ 
    Mensaje <s03> m03; // OK (todas las versiones) 
    Mensaje <s11 > m11; // OK, a partir de C ++ 11 
    static  char  const s17 [] = " hi " ; // Sin enlace (¿la variable local estática no es un enlace?) 
    Mensaje <s17> m17; // OK, de C + +17 inicio 
}

En los tres casos, "hola" inicializa una matriz de caracteres constante y este objeto se utiliza como un parámetro de plantilla declarado con char const *. Esto es válido en todas las versiones de C ++ si el objeto tiene enlace externo (s03), en C ++ 11 y C ++ 14 también si tiene enlace interno (s11), y desde C ++ 17 si no tiene enlace en absoluto .

En los tres casos, los objetos de matriz de caracteres constantes se inicializan con "hola". Este objeto se usa en el parámetro de plantilla declarado como char const *. Si el objeto es un enlace externo (s03), todas las versiones en C ++ son válidas. En C ++ 11 y C ++ 14, si el objeto es un enlace interno, también funcionará. A partir de C ++ 17, si el objeto no está vinculado en absoluto, también funcionará.

 

Vea la Sección 12.3.3 en la página 194 para una discusión detallada y la Sección 17.2 en la página 354 para una discusión de posibles cambios futuros en esta área.

Para una discusión detallada, vea la sección 12.3.3 en la página 194. Para una discusión de posibles cambios a este lugar en el futuro, consulte la sección 17.2 en la página 354.

 

Evitar expresiones inválidas

Evitar expresiones inválidas

 

Los argumentos para los parámetros de plantilla que no son de tipo pueden ser expresiones de tiempo de compilación.

Por ejemplo:

Los parámetros de plantilla sin tipo pueden ser cualquier expresión en tiempo de compilación.

plantilla < int I, bool B>
 clase C; 
C < sizeof ( int ) + 4 , sizeof ( int ) == 4 > c;

Sin embargo, tenga en cuenta que si se usa el operador> en la expresión, debe poner la expresión completa entre paréntesis para que el> anidado finalice la lista de argumentos:

Sin embargo, tenga en cuenta que si ha utilizado el operador ">" en la expresión, debe poner la expresión completa entre paréntesis para anidar la lista de argumentos> final:

C < 42 , sizeof ( int )> 4 > c; // ERROR: El primer ">" finaliza la lista de argumentos de plantilla 

C < 42 , ( sizeof ( int )> 4 )> c; // OK

 

Supongo que te gusta

Origin www.cnblogs.com/5iedu/p/12716483.html
Recomendado
Clasificación