Entiendo que el parámetro de plantilla sin tipo debe ser una expresión integral constante. ¿Alguien puede arrojar luz por qué es así?
template <std::string temp>
void foo()
{
// ...
}
error C2993: 'std::string' : illegal type for non-type template parameter 'temp'.
Entiendo lo que es una expresión integral constante. ¿Cuáles son las razones para no permitir tipos no constantes std::string
como en el fragmento anterior?
Respuestas:
La razón por la que no puede hacer esto es porque las expresiones no constantes no se pueden analizar ni sustituir durante el tiempo de compilación. Podrían cambiar durante el tiempo de ejecución, lo que requeriría la generación de una nueva plantilla durante el tiempo de ejecución, lo que no es posible porque las plantillas son un concepto de tiempo de compilación.
Esto es lo que permite el estándar para los parámetros de plantilla que no son de tipo (14.1 [temp.param] p4):
fuente
Eso no está permitido.
Sin embargo, esto está permitido:
Consulte §14.1 / 6,7,8 en C ++ Standard (2003).
Ilustración:
Salida:
fuente
std::string
puntero u objeto de referencia. Si esa variable fuera local, posiblemente obtendría direcciones diferentes cada vez que se llamara a la función.Necesita poder alterar los argumentos de la plantilla
Ahora, un impl tendría que crear una secuencia única de caracteres para una
std::string
o, para el caso, cualquier otra clase arbitraria definida por el usuario, almacenando un valor particular, cuyo significado no es conocido por la implementación. Además, el valor de los objetos de clase arbitrarios no se puede calcular en el momento de la compilación.Se planea considerar la posibilidad de permitir tipos de clases literales como tipos de parámetros de plantilla para post-C ++ 0x, que se inicializan mediante expresiones constantes. Aquellos se pueden alterar haciendo que los miembros de datos se alteren de forma recursiva de acuerdo con sus valores (para las clases base, por ejemplo, podemos aplicar el cruce de profundidad primero, de izquierda a derecha). Pero definitivamente no funcionará para clases arbitrarias.
fuente
Un argumento de plantilla que no es de tipo proporcionado dentro de una lista de argumentos de plantilla es una expresión cuyo valor se puede determinar en tiempo de compilación. Tales argumentos deben ser:
Además, los literales de cadena son objetos con enlace interno, por lo que no puede usarlos como argumentos de plantilla. Tampoco puede utilizar un puntero global. No se permiten literales de coma flotante, dada la posibilidad obvia de errores de redondeo.
fuente