c++ - sobre - tags para hacer con amigos
¿Por qué la plantilla<T> pero no la plantilla<> se puede definir fuera de un bloque de espacio de nombres? (1)
El problema aquí no es la definición , sino la declaración . No puede inyectar una declaración en un espacio de nombres desde un espacio de nombres diferente, por lo que la especialización debe ser declarada en el espacio de nombres apropiado antes de que se pueda definir en cualquier espacio de nombres que lo incluya.
La definición de la plantilla base se puede hacer en el espacio de nombres externo porque ya se ha declarado , por lo que el código en el espacio de nombres externo proporciona una definición pero no inyecta ninguna declaración en el espacio de nombres.
Tratar:
namespace ns {
class foo
{
template <typename T> int bar (T *);
};
template <>
int foo::bar<int>(int*); // declaration
}
template <typename T>
int ns :: foo :: bar (T*) {
return 0;
}
template <>
int ns :: foo :: bar <int> (int *) {
return 1;
}
Aquí hay un código que no se compila.
namespace ns
{
class foo
{
template <typename T> int bar (T *);
};
}
template <typename T>
int ns :: foo :: bar (T*) // this is OK
{
return 0;
}
template <>
int ns :: foo :: bar <int> (int *) // this is an error
{
return 1;
}
El error es: "especialización de ''template int ns :: foo :: bar (T *)'' en diferentes espacios de nombres [-fpermissive] de la definición de ''template int ns :: foo :: bar (T *)"
Aquí hay una versión que compila:
namespace ns
{
class foo
{
template <typename T> int bar (T *);
};
}
template <typename T>
int ns :: foo :: bar (T*)
{
return 0;
}
namespace ns
{
template <>
int foo :: bar <int> (int *)
{
return 1;
}
}
¿Por qué la segunda definición tiene que estar en un bloque de namespace ns {}
cuando la primera se define bastante feliz con un nombre calificado? ¿Es solo un descuido en el diseño del lenguaje o hay una razón para esto?