class Namespace::Class;
Dlaczego muszę to zrobić ?:
namespace Namespace {
class Class;
}
Używając VC ++ 8.0, kompilator problemy:
błąd C2653: „Przestrzeń nazw”: nie jest nazwą klasy ani przestrzeni nazw
Zakładam, że problem polega na tym, że kompilator nie może stwierdzić, czy Namespace
jest to klasa czy przestrzeń nazw? Ale dlaczego to ma znaczenie, skoro jest to tylko deklaracja wyprzedzająca?
Czy istnieje inny sposób zadeklarowania klasy zdefiniowanej w jakiejś przestrzeni nazw? Powyższa składnia sprawia wrażenie, że „ponownie otwieram” przestrzeń nazw i rozszerzam jej definicję. A co by Class
było, gdyby tak naprawdę nie zostały zdefiniowane w Namespace
? Czy w pewnym momencie spowoduje to błąd?
c++
namespaces
Yong Li
źródło
źródło
A::B
A
Namespace
jest to klasa czy przestrzeń nazw. Po prostu nie zbliżaj się do śladu możliwości rozpoczęcia wojny o język o składnię.Odpowiedzi:
Ponieważ nie możesz. W języku C ++ w pełni kwalifikowane nazwy są używane tylko w odniesieniu do istniejących (tj. Wcześniej zadeklarowanych) jednostek. Nie można ich używać do wprowadzania nowych bytów.
I są w rzeczywistości „wznowienie” przestrzeń nazw zadeklarować nowych podmiotów. Jeśli klasa
Class
zostanie później zdefiniowana jako członek innej przestrzeni nazw - jest to zupełnie inna klasa, która nie ma nic wspólnego z tą, którą tutaj zadeklarowałeś.Gdy dojdziesz do punktu definiowania wstępnie zadeklarowanej klasy, nie musisz ponownie „otwierać” przestrzeni nazw. Możesz zdefiniować go w globalnej przestrzeni nazw (lub dowolnej przestrzeni nazw obejmującej twoją
Namespace
) jakoPonieważ odwołujesz się do jednostki, która została już zadeklarowana w przestrzeni nazw
Namespace
, możesz użyć nazwy kwalifikowanejNamespace::Class
.źródło
Otrzymujesz poprawne odpowiedzi, po prostu spróbuję przeredagować:
class Namespace::Class;
Musisz to zrobić, ponieważ termin
Namespace::Class
mówi kompilatorowi:Ale kompilator nie wie, o czym mówisz, ponieważ nie zna nazwanej przestrzeni nazw
Namespace
. Nawet jeśli istniałaby przestrzeń nazw o nazwieNamespace
, jak w:to nadal nie zadziała, ponieważ nie możesz zadeklarować klasy w przestrzeni nazw spoza tej przestrzeni. Musisz znajdować się w przestrzeni nazw.
Tak więc możesz w rzeczywistości zadeklarować klasę w przestrzeni nazw. Po prostu zrób to:
źródło
Przypuszczam, że z tego samego powodu nie można za jednym razem zadeklarować zagnieżdżonych przestrzeni nazw:
i musisz to zrobić:
źródło
Nie byłoby jasne, jaki właściwie jest typ zmiennej zadeklarowanej w przód. Deklaracja do przodu
class Namespace::Class;
może oznaczaćlub
źródło
Istnieje wiele doskonałych odpowiedzi na temat uzasadnienia odrzucenia tego. Chcę tylko przedstawić nudną standardową klauzulę, która wyraźnie tego zabrania. Dotyczy to C ++ 17 (n4659).
Wspomniany akapit to [nazwa.klasy] / 2 :
Powyższe definiuje, co stanowi deklarację forward (lub powtórną deklarację klasy). W istocie, musi ona być jeden
class identifier;
,struct identifier;
lubunion identifier;
gdzie identifer jest wspólnym słownikowa definicja w [lex.name] :To jest produkcja wspólnego schematu,
[a-zA-Z_][a-zA-Z0-9_]*
który wszyscy znamy. Jak widać, wyklucza toclass foo::bar;
bycie prawidłową deklaracją przekazania, ponieważfoo::bar
nie jest to identyfikator. To w pełni kwalifikowana nazwa, coś innego.źródło