2011-01-05 16 views
6

Jakie są przesłanki wyszukiwania Koeniga?Uzasadnienie wyszukiwania Koeniga

Nie można uniknąć myślenia o tym jak o czymś, co sprawia, że ​​kod jest trudniejszy do odczytania, a więcej - niestabilny.

Nie mogli zdefiniować wyszukiwania Koenig, aby działało tylko w określonych przypadkach (np. Operatorzy nie będący członkami) lub gdy jest to wyraźnie wymagane?

+0

Nigdy o tym nie myślałem. Więc nawet ja chcę to wiedzieć. Dobre pytanie! – Nawaz

Odpowiedz

5

Oryginalny motywacja, IIRC, żeby móc pisać

std::cout << 42; 

bez konieczności zakwalifikowania std::operator<<(std::ostream&, int) jawnie.

Jeśli chcesz wyłączyć wyszukiwanie zależne od argumentów, możesz wyraźnie zakwalifikować nazwę funkcji, np. użyj std::swap zamiast swap, aby uniknąć sprawdzenia, czy swap znajduje się w obszarze nazw, w którym będą mieszkać jego argumenty.

ADL może być również używany z SFINAE do testowania w czasie kompilacji, czy określona jest jakaś funkcja dla danego typu (pozwolę ci to przetestować jako ćwiczenie, jest co najmniej jedno pytanie na ten temat na Stackoverflow).

+0

Myślę, że SFINAE zostało wymyślone po wprowadzeniu ADL. Chodzi mi o to, że chciałbym być zmuszony do wyraźnego określenia, jakiego obszaru nazw użyć (lub wyraźnie powiedzieć, aby zastosować ADL). ... Wyjaśniłem fragment kodu, który napisałem do mojego przyjaciela, który nie mówi w C++; po dziesięciu minutach spędzonych na rozmowach o przestrzeniach nazw zapytał mnie, dlaczego w moim kodzie mógłbym użyć funkcji z innej przestrzeni nazw, nie czyniąc tego wyraźnie.Brzmiałam prawie jak "och, cóż, tak, ponieważ C++ ma również tę drugą regułę, która ..." – peoro

+0

@peoro: C++ ma wiele dziwnych reguł, a to będzie gorsze z C++ 0x. Jednak uważam, że najlepiej jest unikać ADL, jawnie wywołując funkcje członkowskie za pomocą "this->" i używając wyraźnych kwalifikacji, kiedy tylko ma to sens. W większości przypadków nie jest to potrzebne (z wyjątkiem wywołań funkcji członkowskich). I są chwile, kiedy ADL jest świetny. –

+0

@Alexandre C .: Tak, wiem, że można tego uniknąć, ale to nie odpowiada, dlaczego istnieje ADL. Pomyślałem (to jest moja osobista opinia, tak) byłoby prostsze i czystsze, aby go nie mieć, i zmuszono go do tego. W jakich przypadkach jest to świetne? W tej chwili widzę to jak dziwną regułę C++, której można łatwo uniknąć w języku o dobrej składni. – peoro

3

Najsilniejszy przypadek użycia ADL dotyczy takich przypadków.

namespace A 
{ 
    struct S {}; 
    S operator+(const S&, const S&); 
} 

namespace B 
{ 
    A::S test() 
    { 
     A::S a, b; 
     return a + b; 
    } 
} 

Jest także przydatny dla wyboru właściwego swap funkcji w kodzie generycznych, dlatego nie powinno się stosować tylko do operator funkcji. Jest to już dość złożona część normy, dzięki czemu zasady, które uniemożliwiły jej działanie w niektórych przypadkach, mogłyby zwiększyć stopień złożoności, a jaki byłby zysk?

Nie mogę wymyślić żadnego zgrabnego sposobu żądania jawnie tego, który byłby znacznie mniej gadatliwy niż wywoływanie funkcji w innej przestrzeni nazw bezpośrednio i, w każdym przypadku, czyni wyrażenia bardziej złożonymi.

Mamy na myśli coś takiego: return [[ use_adl ]] (a + b); vs. return A::operator+(a, b);?

+0

Właściwie to myślałem o dodaniu jakiegoś słowa kluczowego wewnątrz funkcji, która używa koenigowego wyszukiwania: 'void f (const T & a) {namespaceof (T) :: ...; } '... – peoro

+2

@peroro:' namespaceof (T) 'bardzo dużo brzmi tak, jakbyś określał konkretny obszar nazw do wyszukiwania; w takim przypadku wcale nie potrzebujesz ADL. Równie dobrze możesz użyć kwalifikowanego identyfikatora. –

+0

@Charles Bailey: Tak, ale moje pytanie nadal tam jest. Czy nie byłoby prostsze (dla kompilatorów i dla standardu) i czystsze (dla programistów i dla standardu) mieć operatora jak "namespaceof" zamiast ADL, a będąc zmuszonym do jawnego użycia przestrzeni nazw? – peoro