2011-03-24 11 views
10

Ésta es una pregunta de seguimiento a: Using export keyword with templatesLa separación de interfaz de plantilla y la implementación en C++

Como se mencionó en las respuestas de las preguntas originales 'exportación' está en desuso en C++ 0x y rara vez con el apoyo de los compiladores incluso para C++ 03. Ante esta situación, ¿de qué manera se pueden ocultar las implementaciones reales en archivos lib y simplemente exponer las declaraciones a través de archivos de cabecera, para que el usuario final pueda saber cuáles son las firmas de la API expuesta pero no tiene acceso al código fuente que implementa la misma?

Respuesta

7

En la práctica no se puede.

Solo si tiene un cierto conjunto de especializaciones, puede ponerlas en una biblioteca. La plantilla base no puede colocarse allí.

Por otro lado, el uso de exportación no ocultaba la fuente. El compilador aún lo necesitaba para instanciar nuevas clases de la plantilla.

+1

también es posible declarar únicamente la plantilla base, en cuyo caso la creación de instancias con tipos para los que no se proporciona especialización es imposible. –

+0

Ciertas especializaciones básicamente significan funciones especiales para cada caso (simplemente similar a cualquier API ... No hay uso de la potencia de las plantillas). –

+0

Matthieu M: ¿Esto significa que si estoy usando plantillas para el desarrollo tengo que exponer todo el código fuente desarrollado para el usuario (leer de terceros). ¿No hay forma de hacer cumplir los derechos intelectuales? –

2

En resumen, no se puede. La palabra clave export fue un intento fallido de lograr algo parecido a las bibliotecas de plantillas que no son de origen (aunque ni siquiera se aproxima al nivel de ofuscación que logra el código binario), y no hay reemplazo en el horizonte.

1

Una cosa que he notado a menudo es que una buena porción del código de plantilla , no es una plantilla de hecho, y se puede mover a funciones que no sean de plantilla.

También sucede que la especialización de plantilla de función se considera como funciones regulares: puede definirlas en línea (y marcarlas así) o declararlas en un encabezado e implementarlas en un archivo de origen.

Por supuesto, la especialización significa que usted sabe con qué tipo será ejecutado ...

Tenga en cuenta que lo que está pidiendo es algo antitético.

El objetivo de la plantilla es crear un "patrón" para que el compilador pueda generar clases y funciones para una multitud de tipos no relacionados. Si oculta este patrón, ¿cómo espera que el compilador pueda generar esas clases y funciones?

1

Puede usar la plantilla extern en la mayoría de los compiladores recientes: http://en.wikipedia.org/wiki/C%2B%2B0x#Extern_template

Sin embargo, es imperfecto, ya que sólo se limita instancias de plantilla. La idea es separar la declaración de la plantilla y la implementación en dos archivos separados.

Luego, cuando necesite la plantilla, primero use la plantilla extern para asegurarse de que aún no se haya creado una instancia. Luego, para cada instanciación que necesite (una para std :: vector, otra para std :: vector, etc.), coloque la instanciación en un typedef que estará en una cpp única.

Como hace que el código sea claramente más difícil de entender, no es la mejor solución hasta el momento. Pero funciona: ayuda a minimizar las instancias de plantillas.

Cuestiones relacionadas