c++ templates forward-declaration

c++ - Parámetros predeterminados de la plantilla con declaración directa.



templates forward-declaration (4)

Bueno mismo problema aquí. Pero con STL.

Si uno de mis encabezados usa por ejemplo. std :: vector, entonces tengo que incluir todo el encabezado. A partir de este momento, cada vez que incluyo mi encabezado, incluso si mi código fuente no hace referencia a std :: vector, en todo el encabezado se incluye junto con mi encabezado. Si incluye este encabezado en muchos lugares, esto significará muchos sobrepases.

Así que reenvié a declarar std :: vector y utilicé std :: vector *, pero mi código no quiere compilar debido a los argumentos predeterminados. Si coloco los argumentos predeterminados en mi encabezado, el compilador se niega a compilar el encabezado stl debido a la respetificación del argumento predeterminado.

Lo que estoy tratando de hacer en esta situación es crear mi propia clase Vector que adapta el std :: vector y reenvía todas las llamadas de métodos. Probablemente esto podría resolver el problema.

¿Es posible reenviar declarar una clase que usa argumentos predeterminados sin especificar o conocer esos argumentos?

Por ejemplo, me gustaría declarar boost::ptr_list< TYPE > en una clase de Rasgos sin arrastrar toda la biblioteca de Boost a todos los archivos que incluyan los rasgos. Me gustaría declarar la namespace boost { template<class T> class ptr_list< T >; } namespace boost { template<class T> class ptr_list< T >; } , pero eso no funciona porque no coincide exactamente con la verdadera declaración de clase:

template < class T, class CloneAllocator = heap_clone_allocator, class Allocator = std::allocator<void*> > class ptr_list { ... };

¿Mis opciones son solo para vivir con él o para especificar boost::ptr_list< TYPE, boost::heap_clone_allocator, std::allocator<void*> en mi clase de rasgos? (Si uso este último, también tendré que reenviar declare boost::heap_clone_allocator e incluir <memory> , supongo.)

He revisado el libro de Stroustrup, SO y el resto de Internet y no he encontrado una solución. Por lo general, a las personas les preocupa no incluir STL, y la solución es "solo incluir los encabezados de STL". Sin embargo, Boost es una biblioteca mucho más masiva y de uso intensivo de compiladores, por lo que preferiría omitirla a menos que sea absolutamente necesario.


Cualquier unidad de compilación que use su instalación que declare de manera progresiva tendrá que incluir los encabezados de impulso de todos modos, excepto en el caso de que tenga ciertos programas que no usarán la parte de impulso de su instalación.

Es cierto que al declarar hacia adelante, puede evitar incluir los encabezados de impulso para dichos programas. Pero tendrá que incluir manualmente los encabezados boost (o tener un #ifdef ) para aquellos programas que realmente usan la parte boost.

Tenga en cuenta que se podrían agregar más parámetros de plantilla predeterminados en una futura versión de Boost. Yo aconsejaría en contra de esta ruta. Lo que consideraría, si su objetivo es acelerar los tiempos de compilación, es usar #define para indicar si el código que usa esa biblioteca de boost debe estar deshabilitado. De esta manera usted evita la molestia de la declaración hacia adelante.


No creo que pueda reenviar una plantilla con argumentos predeterminados a menos que la biblioteca en cuestión proporcione su propio encabezado de declaración hacia adelante. Esto se debe a que no puede volver a especificar los argumentos predeterminados (incluso si coinciden ... gcc seguirá informando "error: redefinición del argumento predeterminado").

Por lo que yo sé, la solución es que la biblioteca proporcione un encabezado de declaración hacia adelante Foo_fwd.h:

#ifndef INCLUDED_Foo_fwd_h_ #define INCLUDED_Foo_fwd_h_ template<class T, class U=char> class Foo; // default U=char up here #endif

y luego la implementación completa en Foo.h sería:

#ifndef INCLUDED_Foo_h_ #define INCLUDED_Foo_h_ #include "Foo_fwd.h" template<class T, class U> class Foo { /*...*/ }; // note no U=char here #endif

Así que ahora su código también podría usar Foo_fwd.h ... pero desafortunadamente, dado que este enfoque requiere modificar el Foo.h original para eliminar los argumentos predeterminados, no se puede escalar a bibliotecas de terceros. ¿Tal vez deberíamos presionar al equipo de C ++ 0x para permitir una respuesta equivalente de los argumentos de la plantilla predeterminada, à la typedefs ...?


Sí. Los argumentos predeterminados de la plantilla pueden especificarse en cualquier momento y en cualquier lugar, siempre que las declaraciones no entren en conflicto entre sí. En última instancia, se fusionan a partir de las diversas declaraciones.

Incluso esto es legal:

template< class A, class B, class C = long > class X; template< class A, class B = int, class C > class X; template< class A = short, class B, class C > class X { };

Un ejemplo similar se da en §14.1 / 10. De acuerdo con ese párrafo, los argumentos predeterminados de la función se comportan de manera similar.

¡Buena suerte en conseguir que la declaración a futuro se comporte a sí misma y no se burle de todo!