Konu Tarihi: ADL (Argument Dependent Lookup), Koenig lookup olarak da bilinir, C++'de operatör aşırı yüklenmesini desteklemek için (özellikle kullanıcı türleri için operator<< ve operator>> üzerinde) ilk kez ortaya çıkmıştır. Amaç, ad alanlarını ve kullanıcı türlerini birleştirirken fonksiyonları doğru bir şekilde bulmaktır.
Problem: Standart fonksiyon arama mekanizması, çağrı noktasından farklı bir ad alanında tanımlı olan bir fonksiyonu "görmeyebilir". ADL bu problemi çözer: derleyici, fonksiyonun argüman türlerinin ad alanlarını dikkate alarak isimleri çözer. Bu mekanizma bazen beklenmedik aşırı yüklenme seçimine veya belirsizliğe yol açar.
Çözüm: Bir fonksiyon çağrıldığında, argümanları kullanıcı ad alanlarından nesneler olduğunda, derleyici sadece mevcut kapsamda değil, aynı zamanda argüman türleriyle ilgili tüm ad alanlarında uygun aşırı yüklenmiş fonksiyonları arar.
Kod örneği:
namespace lib { struct Widget {}; void do_something(const Widget&) { std::cout << "Widget" << std::endl; } } using lib::Widget; void call(const Widget& w) { do_something(w); // do_something ADL ile bulunur }
Ana özellikler:
İki ad alanında aynı isimde bir fonksiyon tanımlarsanız ve ikinci ad alanından bir nesne geçirirseniz, hangisi çağrılacak?
Argümanın ad alanındaki fonksiyon, argümanlarla uyumluysa ADL sayesinde seçilir:
namespace A { struct S {}; void f(const S&) { std::cout << "A!"; } } namespace B { struct S {}; void f(const S&) { std::cout << "B!"; } } A::S a; B::S b; f(a); // ADL ile A::f çağrılacak f(b); // ADL ile B::f çağrılacak
ADL, şablon fonksiyonlarla çalışır mı?
Evet, eğer şablon fonksiyonu argüman türüyle aynı ad alanında tanımlanmışsa, ADL bu türle çağrıldığında onu bulacaktır.
Fonksiyon işaretçileri için ADL çalışır mı?
Hayır, ADL fonksiyonun adresini alırken (örneğin, bir işaretçi alırken) uygulanmaz. Sadece fonksiyon doğrudan çağrıldığında.
Proje, her bir ad alanında kendi print() fonksiyonu olan birkaç üçüncü taraf kütüphaneyi içe aktardı. Ana kodda, farklı sınıflardan nesnelerle print() kullanılıyordu. ADL sayesinde derleyici, fonksiyonu yanlış ad alanından "seçmeye" başladı.
Artılar:
Eksiler:
Qualified call kullanımı (ad alanını açıkça belirtme):
lib::do_something(w); // Açıkça!
Artılar:
Eksiler: