¿Hay alguna manera de definir una plantilla de función en un encabezado y hacerla inaccesible a los archivos que incluyen el encabezado?
Tengo una plantilla de clase que se ve así:
foo.h
template<class C>
class Foo
{
public:
void memberFunc();
};
Incluye “foo.tpp”
foo.tpp
“`
void Foo::memberFunc()
{
…
}
Ignora el archivo .tpp, es solo algo que hago para dar la ilusión de separar la declaración y la implementación, obviamente eso no es (exactamente) posible con las plantillas.
Mi archivo de implementación es mucho más largo en realidad, y dentro de él tengo algunas plantillas de funciones auxiliares de ámbito global que utilizan las funciones miembro, funciones que no tienen sentido como funciones miembro y que no quiero que los usuarios de la clase tengan nada que ver.
template
template
template
void Foo
{
…
helper1
…
helper2
…
}
Esto lo hago todo el tiempo en archivos de implementación .cpp y olvidé que cuando lo hago en esta versión ficticia de un archivo .cpp, la declaración e implementación de estas pequeñas funciones auxiliares en realidad terminan en el archivo de encabezado de la plantilla de clase. Esto lleva a que los usuarios del archivo de encabezado de la plantilla de clase tengan sus espacios de nombres llenos de funciones auxiliares que son inútiles fuera de las implementaciones de las funciones miembro.
Obviamente, podría simplemente ponerlas en un espacio de nombres:
namespace foo_helpers
{
template
template
}
Pero aún así, esto lleva a que el código externo pueda utilizar estas funciones. Solo importan para la implementación de las funciones miembro y quiero que se refleje.
Al buscar una solución, aprendí sobre el concepto de espacios de nombres sin nombre. Según entiendo, solo permiten que la unidad de traducción actual acceda a su contenido. Eso suena exactamente a lo que necesito, así que cambié las funciones auxiliares a esto:
namespace
{
template
template
}
Pero no funciona, las funciones todavía se pueden utilizar en los archivos que incluyen el encabezado.
¿Hay alguna manera de ocultar estas funciones auxiliares del código externo?
davy.ai
Sí, hay una manera de ocultar las funciones auxiliares del código externo utilizando espacios de nombres sin nombre. El problema con la implementación actual es que el espacio de nombres sin nombre está en el archivo de encabezado, lo que lo hace accesible para cualquier unidad de traducción que incluya el encabezado. Para solucionar esto, puede mover el espacio de nombres sin nombre al archivo “.tpp”, que no es incluido por el código externo.
Aquí hay una implementación actualizada:
foo.h
foo.tpp
Al mover el espacio de nombres sin nombre al archivo “.tpp”, las funciones auxiliares solo son accesibles dentro de la unidad de traducción donde se incluye el archivo “.tpp” (es decir, dentro del mismo archivo que la definición de la plantilla de clase). El código externo que incluye el archivo de encabezado no tendrá acceso a las funciones auxiliares.
¡Espero haber sido de ayuda! Háganme saber si tienen alguna pregunta adicional.