Koenig Lookup , atau Argument Dependent Lookup , menjelaskan bagaimana nama yang tidak memenuhi syarat dicari oleh kompiler di C ++.
Standar C ++ 11 § 3.4.2 / 1 menyatakan:
Ketika ekspresi postfix dalam panggilan fungsi (5.2.2) adalah id yang tidak memenuhi syarat, ruang nama lain yang tidak dipertimbangkan selama pencarian biasa tanpa pengecualian (3.4.1) dapat dicari, dan di ruang nama tersebut, deklarasi fungsi namespace-lingkup teman ( 11.3) tidak terlihat dapat ditemukan. Modifikasi untuk pencarian ini bergantung pada jenis argumen (dan untuk argumen templat templat, namespace argumen templat).
Dalam istilah yang lebih sederhana, Nicolai Josuttis menyatakan 1 :
Anda tidak harus memenuhi syarat namespace untuk fungsi jika satu atau lebih tipe argumen didefinisikan dalam namespace fungsi.
Contoh kode sederhana:
namespace MyNamespace
{
class MyClass {};
void doSomething(MyClass);
}
MyNamespace::MyClass obj; // global object
int main()
{
doSomething(obj); // Works Fine - MyNamespace::doSomething() is called.
}
Dalam contoh di atas tidak ada using
-deklarasi atau -direktif using
tetapi masih kompiler dengan benar mengidentifikasi nama yang tidak memenuhi syarat doSomething()
sebagai fungsi yang dinyatakan dalam namespaceMyNamespace
dengan menerapkan pencarian Koenig .
Bagaimana cara kerjanya?
Algoritma memberitahu kompiler untuk tidak hanya melihat lingkup lokal, tetapi juga ruang nama yang berisi tipe argumen. Jadi, dalam kode di atas, kompiler menemukan bahwa objek obj
, yang merupakan argumen fungsi doSomething()
, adalah milik namespace MyNamespace
. Jadi, terlihat di namespace itu untuk menemukan deklarasidoSomething()
.
Apa keuntungan dari pencarian Koenig?
Seperti yang ditunjukkan contoh kode sederhana di atas, pencarian Koenig memberikan kemudahan dan kemudahan penggunaan bagi programmer. Tanpa pencarian Koenig akan ada overhead pada programmer, untuk berulang kali menentukan nama-nama yang memenuhi syarat, atau sebaliknya, menggunakan banyakusing
-deklarasian.
Mengapa kritik terhadap pencarian Koenig?
Ketergantungan yang berlebihan pada pencarian Koenig dapat menyebabkan masalah semantik, dan terkadang membuat programmer lengah.
Pertimbangkan contoh std::swap
, yang merupakan algoritma perpustakaan standar untuk bertukar dua nilai. Dengan pencarian Koenig kita harus berhati-hati saat menggunakan algoritma ini karena:
std::swap(obj1,obj2);
mungkin tidak menunjukkan perilaku yang sama dengan:
using std::swap;
swap(obj1, obj2);
Dengan ADL, versi mana dari swap
fungsi mana yang dipanggil akan bergantung pada namespace argumen yang diteruskan ke sana.
Jika ada namespace A
dan jika A::obj1
, A::obj2
& A::swap()
ada maka contoh kedua akan menghasilkan panggilan keA::swap()
, yang mungkin bukan yang diinginkan pengguna.
Selanjutnya, jika karena alasan kedua A::swap(A::MyClass&, A::MyClass&)
dan std::swap(A::MyClass&, A::MyClass&)
didefinisikan, maka contoh pertama akan memanggil std::swap(A::MyClass&, A::MyClass&)
tapi yang kedua tidak akan dikompilasi karena swap(obj1, obj2)
akan ambigu.
Hal sepele:
Kenapa disebut "Koenig lookup"?
Karena itu dirancang oleh mantan AT&T dan peneliti dan programmer Bell Labs, Andrew Koenig .
Bacaan lebih lanjut:
1 Definisi pencarian Koenig adalah seperti yang didefinisikan dalam buku Josuttis, The C ++ Standard Library: A Tutorial and Reference .