Sztuczka Bartona-Nackmana
Sztuczka Bartona-Nackmana to termin ukuty przez komitet normalizacyjny C++ ( ISO / IEC JTC1 / SC22 WG21 ) w odniesieniu do idiomu wprowadzonego przez Johna Bartona i Lee Nackmana jako ograniczone rozszerzenie szablonu .
Idiom
funkcji zaprzyjaźnionej w klasie, która pojawia się w komponencie szablonu klasy podstawowej dziwnie powtarzającego się wzorca szablonu (CRTP).
// Szablon klasy do wyrażenia interfejsu porównywania równości. szablon < nazwa typu T > class equal_comparable { przyjaciel bool operator == ( T const & a , T const & b ) { return a . równy_do ( b ); } przyjaciel bool operator != ( T const & a , T const & b ) { return ! za . równy_do ( b ); } }; // Klasa value_type chce mieć == i !=, więc wywodzi się z // equal_comparable z samą sobą jako argumentem (czyli CRTP). klasa typ_wartości : prywatna równa_porównywalna < typ_wartości > { publiczna : bool równa_to ( typ_wartości stała & rhs ) stała ; // do zdefiniowania };
Kiedy tworzony jest szablon klasy, taki jak equal_comparable
, definicje znajomych w klasie tworzą funkcje nieszablonowe (i nieczłonkowskie) (w tym przypadku funkcje operatora). W momencie wprowadzenia tego idiomu (1994) język C++ nie definiował częściowego uporządkowania przeciążonych szablonów funkcji, w wyniku czego przeciążanie szablonów funkcji często powodowało niejasności. Na przykład próba przechwycenia ogólnej definicji operatora==
as
szablon < nazwa typu T > bool operator == ( T const & a , T const & b ) { /* ... */ }
zasadniczo byłoby niezgodne z inną definicją, np
szablon < nazwa typu T > bool operator == ( Tablica < T > const & a , Array < T > const & b ) { /* ... */ }
Sztuczka Bartona-Nackmana osiąga zatem cel, jakim jest zapewnienie ogólnego operatora równości zdefiniowanego przez użytkownika bez konieczności radzenia sobie z takimi niejasnościami. Przymiotnik ograniczony w nazwie idiomu odnosi się do faktu, że podana definicja funkcji w klasie jest ograniczona (dotyczy tylko) do specjalizacji danego szablonu klasy.
Termin ten jest czasami błędnie używany w odniesieniu do dziwnie powtarzającego się wzoru szablonu (CRTP). Jak wyjaśniono powyżej, sztuczka Bartona-Nackmana jest zamiast tego odrębnym idiomem (który opiera się na CRTP).
Jak to działa
Gdy kompilator napotka wyrażenie
v1 == v2
gdzie v1
i v2
są typu value_type
, podejmuje próbę wyszukiwania zależnego od argumentów (ADL) dla operatora==
. To wyszukiwanie obejmuje uwzględnienie funkcji zaprzyjaźnionych zadeklarowanych w value_type
i jej klasach bazowych. (Zauważ, że gdyby wartość_typu
była niekompletną instancją szablonu, program ADL wyzwoliłby jej pełną instancję).
Sztuczka Bartona – Nackmana pierwotnie opierała się nie na ADL, ale na funkcji C++ zwanej „wstrzykiwaniem nazwy znajomego”, w której deklaracja funkcji znajomego w klasie sprawiała, że nazwa funkcji była widoczna w bezpośrednio otaczającym zakresie przestrzeni nazw (prawdopodobnie w zasięgu globalnym) . Badając możliwość usunięcia wstrzykiwania nazwy znajomego z języka programowania C++, stwierdzono, że idiom Bartona i Nackmana jest jedynym rozsądnym zastosowaniem tej reguły językowej. Ostatecznie zasady wyszukiwania zależnego od argumentów zostały dostosowane, aby zastąpić wstrzykiwanie imienia znajomego mniej drastycznym mechanizmem, opisanym powyżej, który utrzymywał ważność techniki Bartona i Nackmana. Warto zauważyć, że w konsekwencji tej zmiany wyrażenie
::operator==(v1,v2)
nie jest już ważny, ponieważ kwalifikowane nazwy nie podlegają ADL, a deklaracje znajomych nie są znajdowane za pomocą zwykłego wyszukiwania. Należy również zauważyć, że przyjaciela
jest niezbędny, nawet jeśli zdefiniowane funkcje przyjaciela nie potrzebują w rzeczywistości dostępu do niepublicznych członków klasy befriending.
Zobacz też
- Bibliografia _ Nackman, Lee R. (1994). C++ naukowy i inżynierski: wprowadzenie z zaawansowanymi technikami i przykładami . Addison-Wesley . ISBN 0-201-53393-6 .
- ^ „Alternatywa dla wstrzykiwania nazw z szablonów” (PDF) . 26 września 1995 . Źródło 12 kwietnia 2005 .
Dalsza lektura
- Vandevoorde, Dawid; Josuttis, Nicolai M.; Gregor, Douglas (2017). Szablony C++: kompletny przewodnik (wyd. 2). Addison-Wesley . ISBN 978-0-321-71412-1 .