Achtergrond van de vraag: ADL (Argument Dependent Lookup), ook bekend als Koenig lookup, verscheen voor het eerst in C++ ter ondersteuning van operatoroverloading (vooral operator<< en operator>> voor gebruikersgedefinieerde types). Het doel is om functies correct te vinden bij het mengen van naamruimten en gebruikersgedefinieerde types.
Probleem: Het standaardmechanisme voor het zoeken naar functies kan een functie "missen" als deze is gedeclareerd in een andere namespace dan het punt van aanroep. ADL lost dit probleem op: de compiler houdt rekening met de naamruimte van de argumenttypes van de functie om namen op te lossen. Ditzelfde mechanisme kan soms leiden tot onverwachte keuze van overbelasting of ambiguïteiten.
Oplossing: Wanneer een functie wordt aangeroepen waarvan de argumenten objecten zijn uit gebruikerspecifieke naamruimten, zoekt de compiler naar geschikte overloaded functies, niet alleen in de huidige scope, maar in alle naamruimten die verband houden met de types van de argumenten.
Voorbeeldcode:
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 wordt gevonden via ADL }
Belangrijkste kenmerken:
Als je een functie met dezelfde naam in twee naamruimten declareert en een object van de tweede doorgeeft, welke wordt dan aangeroepen?
De functie uit de naamruimte van het argument, als deze geschikt is voor de argumenten, zal worden gekozen door ADL:
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); // roept A::f aan via ADL f(b); // roept B::f aan via ADL
Werkt ADL met sjabloonfuncties?
Ja, als de sjabloonfunctie is gedefinieerd in de namespace die overeenkomt met het type van het argument, zal ADL deze vinden bij het aanroepen met dat type.
Zal ADL werken voor functiepointers?
Nee, ADL wordt niet toegepast bij het verkrijgen van een pointer naar een functie (bijvoorbeeld, bij het nemen van het adres daarvan). Alleen bij de directe aanroep van de functie.
Een project heeft verschillende externe bibliotheken aangesloten, waarbij in elke namespace zijn eigen print() was. In de hoofdcode werd print() gebruikt met objecten van verschillende klassen. Door ADL begon de compiler de functie uit de verkeerde naamruimte te "kiezen".
Voordelen:
Nadelen:
Gebruik van qualified call (expliciete vermelding van namespace):
lib::do_something(w); // Expliciet!
Voordelen:
Nadelen: