Pregunta

En C ++ se especifica enlace interno envolviendo sus definiciones de clase y función dentro de un espacio de nombres en el anonimato. También puede crear una instancia explícita plantillas, pero para ser normas conformes cualquier instanciaciones explícitas de las plantillas debe ocurrir en el mismo espacio de nombres. AFAICT esto debe compilar, pero GCC falla en él:

namespace foo {

template<class T>
class bar {};

}

using namespace foo;

namespace {
template class bar<int>;
}

int main()
{
    return 0;
}

Con el error:

namespace_test.cpp:11: error: explicit instantiation of 'class bar<int>' in namespace '<unnamed>' (which does not enclose namespace 'foo')

Lo que es interesante porque espacio de nombre en el anonimato debe el ser simplemente especificando vinculación, no es realmente un espacio de nombre que funciona como y el espacio global sin duda encierra foo, ya que espacio de nombre encierra todas. Pero incluso esto no funciona:

template<class T>
class bar {};

using namespace foo;

namespace {
template class bar<int>;
}

int main()
{
    return 0;
}

¿Qué falla con el mismo error, simplemente lista el espacio de nombres global en vez:

namespace_test.cpp:11: error: explicit instantiation of 'class bar<int>' in namespace '<unnamed>' (which does not enclose namespace '::')

: /

¿Fue útil?

Solución

Un espacio de nombres en el anonimato es lógicamente equivalente a

namespace _TU_specific_unique_generated_name
{
    // ...
}
using namespace _TU_specific_unique_generated_name;

Un espacio de nombres, anónimos o no, no tiene ningún efecto sobre la vinculación de sus miembros. En particular, los miembros de un espacio de nombres en el anonimato no mágicamente conseguir enlace interno.

Otros consejos

En primer lugar: Usted está explícitamente instanciar una plantilla de clase, no se está definiendo una nueva plantilla de clase. Lo

template class bar<int>;

dice que es "por favor instanciar la barra de plantilla de clase de tipo int aquí". No se puede hacer eso en otro espacio de nombres, al igual que no puede especializarse parcialmente una plantilla de clase en otro espacio de nombres. En particular, se debe haber definido la plantilla para crear una instancia de forma explícita, y en su ejemplo, no hay (espacio de nombres en el anonimato) :: barra de <>, solamente foo :: bar <>.

En segundo lugar: El espacio de nombres en el anonimato es un espacio de nombre real (que es distinta en cada unidad de traducción, sin embargo). También no cambia mágicamente vinculación. Todo lo declarado en el interior del espacio de nombres {} tiene todavía la vinculación por defecto, al igual que en cualquier otro ámbito de espacio de nombres. IIRC, incluso se ha añadido para permitir la traducción objetos unidad privada, aún sin vinculación externa.

Creo que tienes tu respuesta - espacios de nombres anónimos son distintas, espacios de nombres únicos. Por cierto, el compilador genera cierta entero grande al azar para representar ese espacio de nombres interno.

De acuerdo con BS (sección 8.2.5.1) el espacio de nombres global tiene acceso al espacio de nombres en el anonimato (sin nombre), pero no dice explícitamente lo contrario.

Yo esperaría que tendría que especificar el espacio de nombres con una instrucción using o totalmente calificar mención de otros espacios de nombres dentro del espacio de nombres sin nombre ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top