2009-07-10 14 views
6

W C++ określasz wewnętrzne powiązanie, zawijając definicje klas i funkcji w anonimowym obszarze nazw. Można również jawnie tworzyć instancje szablonów, ale aby standardy były zgodne z jawnymi wystąpieniami szablonów, muszą występować w tej samej przestrzeni nazw. AFAICT powinno to skompilować, ale GCC nie działa na niego:Czy anonimowy obszar nazw obejmuje wszystkie przestrzenie nazw?

namespace foo { 

template<class T> 
class bar {}; 

} 

using namespace foo; 

namespace { 
template class bar<int>; 
} 

int main() 
{ 
    return 0; 
} 

z błędem:

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

co ciekawe, ponieważ nazw anonimowy powinien być po prostu określenie powiązań, naprawdę nie funkcjonuje jako nazw i globalna przestrzeń nazw zdecydowanie obejmuje foo, ponieważ zamyka wszystkie przestrzenie nazw. Ale nawet to nie działa !:

template<class T> 
class bar {}; 

using namespace foo; 

namespace { 
template class bar<int>; 
} 

int main() 
{ 
    return 0; 
} 

Które nie powiedzie się z powodu tego samego błędu, po prostu wymieniając nazw globalnego zamiast:

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

:/

+0

Która wersja GCC - lub które opcje kompilatora - lub która platforma? Próbowałem pierwszej próbki z G ++ 4.0.1 na MacOS X zi bez -Wall i skompilowałem ją bez skargi lub ostrzeżenia. –

+0

GCC 4.2 w systemie Solaris. –

Odpowiedz

10

anonimowy nazw jest logicznie równoważne

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

Przestrzeń nazw, anonimowy czy inaczej, nie ma żadnego wpływu na wiązanie jej członków. W szczególności członkowie anonimowej przestrzeni nazw nie uzyskują magicznego połączenia wewnętrznego.

+1

Dodam oczywiste, że rzeczy w _TU_specific_unique_generated_name nie mogą być używane poza plikiem. – Valentein

+0

Jest to dokładnie opisany w sposób standardowy, zaakceptowany. –

6

Chyba masz odpowiedź - anonimowe przestrzenie nazw są odrębnymi, unikalnymi przestrzeniami nazw. BTW, kompilator generuje losową dużą liczbę całkowitą, aby wewnętrznie reprezentować tę przestrzeń nazw.

0

Według Stroustrup (sekcja 8.2.5.1) globalnej przestrzeni nazw ma dostęp do przestrzeni nazw (nienazwanej) anonimowego, ale nie wyraźnie powiedzieć coś przeciwnego.

Spodziewam trzeba by określić nazw z wykorzystaniem rachunku lub w pełni kwalifikuje się odnośniki do innych nazw wewnątrz przestrzeni nazw bezimiennego ...

7

pierwsze: Jesteś wyraźnie instancji szablonu klasy, nie definiują nowy szablon klasy. To, co oznacza: "proszę utworzyć instancję paska szablonów klas dla typu int tutaj" #:. Nie można tego zrobić w innym obszarze nazw, tak jak nie można częściowo wyspecjalizować szablonu klasy w innym obszarze nazw. W szczególności musi zostać zdefiniowany szablon do jawnego utworzenia instancji, aw twoim przykładzie nie ma (anonimowej przestrzeni nazw) :: bar <>, tylko foo :: bar <>.

drugie: namespace anonimowy jest prawdziwym nazw (to odrębne w każdej jednostce tłumaczeniowej, choć). Nie zmienia również magicznie powiązania. Wszystko zadeklarowane w przestrzeni nazw {} ma nadal domyślne powiązanie, tak jak w każdym innym obszarze nazw. IIRC, został nawet dodany, aby umożliwić jednostce tłumaczeniowej prywatne, ale zewnętrzne obiekty łączące.