2010-08-10 4 views
19

lectura C++ Templates: The Complete Guide y dice¿Por qué las plantillas no se pueden declarar en una función?

Tenga en cuenta que las plantillas no pueden ser declarados en una función

No da explicación y/o referencia cruzada a cualquier otro capítulo en el libro o recurso externo.

Podría alguien ayudarme a explicar esto. Probablemente se explica más adelante en el libro pero aún no está allí. Si lo explicamos antes, me lo debería haber perdido.

Ejemplo:

int main() 
{ 
    class DummyClass // This compiles ok 
    { 
    int object; 
    }; 

    template <typename T> // compile error "expected primary-expression before "template"" 
    class DummyTemplate 
    { 
    T object; 
    }; 

    return 0; 
} 

no entiendo el mensaje de error de gcc tampoco. El mensaje de error dice:

expected primary-expression before "template" 
+0

No puede declarar nuevas clases, así es, así es, supongo. –

+1

Hay varias respuestas que básicamente dicen "no se puede porque no se puede". ¿Alguien sabe si hay una buena razón para evitar hacer esto? –

+0

Los argumentos de la plantilla deben tener un enlace externo. En cuanto a por qué es una necesidad, hay algunas sugerencias proporcionadas por Greg Comeau en este clC++. Discusión moderada @ http://groups.google.com/group/comp.lang.c++moderated/browse_thread/thread/f822a008746d1e68/2e9e48a43743e9e1 ? lnk = gst & q = por qué + local + plantillas # 2e9e48a43743e9e1 – Abhay

Respuesta

0

Esto significa que no puede hacer algo como las siguientes declaraciones de plantilla

void foo() 
    { 
     template <typename T> //Error 
     T something; 
    } 

sólo se permiten al espacio de nombres, o el ámbito mundial, la clase. :)

¿Cuál es el razonamiento detrás de esto?

No está permitido porque el estándar lo dice.

ISO C++ - 98 (Sección 14,2)

Una declaración plantilla sólo puede aparecer como una declaración de espacio de nombres alcance o clase.

¿Tiene sentido?

+2

si.Gracias. La pregunta es por qué este es el caso. ¿Cuál es el razonamiento detrás de esto? – dubnde

+3

'¿Cuál es el razonamiento detrás de esto?'. No conozco muchos tecnicismos con respecto a la implementación de la declaración de plantilla dentro de una función, pero no está permitido por la norma. ** ISO C++ (14.2) ** dice 'A * declaración de plantilla * puede aparecer solo como un espacio de nombres o declaración de alcance de clase' :) –

+4

+1. Gracias. Sí, tiene sentido. Veo que el estándar no lo permite. Sin embargo, sería útil comprender por qué. He visto preguntas sobre lo que los estándares permiten (no) responder con algunas explicaciones para respaldar el estándar. Muy útil para estudiantes como yo. Esto de ninguna manera elimina nada de esta muy buena respuesta. – dubnde

0

¿Cuál sería exactamente el uso? Entonces, ¿puede declarar variables de plantilla que solo puede usar dentro de la función? ¿Eso es realmente útil?

+0

+1 para evitar el código de caos. –

+0

Sí. Puedo hacer esto con estructuras y clases. Solo se puede pensar en uno de los objetos funcionales con respecto a las clases/estructuras para usar con algoritmos dentro de una función. No es obligatorio, pero lo hago para mantener las clases/estructuras cerca de donde las uso. Presumiblemente podría tener alguna razón, pero esto es más un ejercicio de aprendizaje. El hecho de que puede no ser útil es una discusión diferente, supongo. – dubnde

+0

Su utilidad no es realmente otra discusión, la OMI es muy pertinente a esta. Si esto estuviera permitido, ¿cómo lo usarías? Las entrañas de una función no son visibles para la persona que llama, entonces, ¿cómo creará una instancia del parámetro de la plantilla con el tipo apropiado al llamar a esta función? – Praetorian

2

La respuesta corta de por qué esto es así es porque así lo querían los tipos que escribieron los compiladores y estándares c/C++. Las plantillas dentro de las funciones deben haber sido consideradas demasiado caóticas y/o difíciles de entender o analizar, por lo que lo prohibieron.

+0

Gracias. Muy comprensible y puedo ver que tiene mucho sentido. ¿Alguna referencia? – dubnde

+0

@MeThinks: Mira mi comentario a tu comentario. –

1

El único momento en que esto sería útil sería si creó varias instancias de la plantilla con diferentes tipos dentro de una función. Aparte sus clases privadas de sus funciones. Si eso comienza a llenar sus clases, entonces son demasiado grandes y deben ser refactorizados.

+0

Este es un buen consejo. – dubnde

+2

Sin embargo, estoy de acuerdo en que es una extraña inconsistencia en el lenguaje. Como todo el mundo dice, simplemente apúntalo a: "porque así es". – Cirdec

1

Supongo que es difícil de implementar, por eso no está permitido. Escribir plantillas de clase fuera de las funciones es una solución aceptable de la otra mano.

26

El problema probablemente esté relacionado con la forma histórica en que se implementaron las plantillas: las primeras técnicas de implementación (y algunas todavía se usan hoy en día) requieren que todos los símbolos en una plantilla tengan un enlace externo. (La instanciación se realiza generando el código equivalente en un archivo separado.) Y los nombres definidos dentro de una función nunca tienen vínculos, y no pueden ser referidos fuera del alcance en el que fueron definidos.

+1

suena razonable. – iammilind

+4

Esta debería ser la respuesta aceptada, ya que al menos trató de dar el razonamiento detrás de esto, no solo "porque el estándar lo dice". –

Cuestiones relacionadas