Ostatnio widziałem dziwną funkcję C ++: wstrzyknięta nazwa klasy .
class X { };
X x1;
class X::X x2; // class X::X is equal to X
class X::X::X x3; // ...and so on...
Ale nie mogę zrozumieć, dlaczego ta funkcja jest konieczna. Czy jest jakaś praktyka, która wymaga tej funkcji?
Słyszałem, że ta funkcja nie istniała w starym C ++. A kiedy został wprowadzony? C ++ 03? C ++ 11?
Odpowiedzi:
Nazwa wstrzykniętej klasy oznacza, że
X
jest zadeklarowana jako element członkowskiX
, więc wyszukiwanie nazwy wewnątrzX
zawsze znajduje bieżącą klasę, a nie inną,X
która może być zadeklarowana w tym samym zakresie obejmującym, np.Czy
create()
funkcja tworzy tymczasowyX
obiekt czy wywołuje funkcjęX
? W zakresie przestrzeni nazw wywołałoby funkcję, więc celem wstrzykniętej nazwy klasy jest zapewnienie, że w treściX
nazwy zawsze znajdzie samą klasę (ponieważ wyszukiwanie nazw rozpoczyna się we własnym zakresie klasy przed zajrzeniem do otaczającego zakres).Jest to również pomocne w szablonach klas, gdzie wstrzyknięta nazwa klasy może być używana bez listy argumentów szablonu, np. Używając po prostu
Foo
zamiast pełnego identyfikatora szablonuFoo<blah, blah, blah>
, więc łatwo jest odwołać się do bieżącej instancji. Zobacz DR 176, aby zobaczyć zmianę między C ++ 98 i C ++ 03, która to wyjaśniła.Pomysł na nazwę klasy wstrzykiwanej był obecny w C ++ 98, ale terminologia była nowa dla C ++ 03.
C ++ 98 mówi:
Drugie zdanie zostało zmienione przez DR 147, więc C ++ 03 mówi w [klasa] / 2:
Jeszcze przed C ++ 98 ARM ma z grubsza równoważne sformułowanie, co oznacza, że nazwa klasy może być zawsze używana w treści klasy, aby odwołać się do samej klasy:
źródło