A Pesquisa Koenig , ou Pesquisa Dependente de Argumento , descreve como os nomes não qualificados são pesquisados pelo compilador no C ++.
O padrão C ++ 11, § 3.4.2 / 1, declara:
Quando a expressão postfix em uma chamada de função (5.2.2) é um ID não qualificado, outros espaços para nome não considerados durante a pesquisa não qualificada usual (3.4.1) podem ser pesquisados e, nesses espaços para nome, declarações de função de amigo no escopo do espaço para nome ( 11.3) não visível de outra forma pode ser encontrado. Essas modificações na pesquisa dependem dos tipos dos argumentos (e dos argumentos do modelo, o espaço para nome do argumento do modelo).
Em termos mais simples, Nicolai Josuttis afirma 1 :
Você não precisa qualificar o espaço para nome para funções se um ou mais tipos de argumento estiverem definidos no espaço para nome da função.
Um exemplo de código simples:
namespace MyNamespace
{
class MyClass {};
void doSomething(MyClass);
}
MyNamespace::MyClass obj; // global object
int main()
{
doSomething(obj); // Works Fine - MyNamespace::doSomething() is called.
}
No exemplo acima, não há uma using
declaração-nem um diretório, using
mas ainda assim o compilador identifica corretamente o nome não qualificado doSomething()
como a função declarada no espaço para nome MyNamespace
aplicando a pesquisa Koenig .
Como funciona?
O algoritmo diz ao compilador para não apenas examinar o escopo local, mas também os espaços para nome que contêm o tipo do argumento. Assim, no código acima, o compilador descobre que o objeto obj
, que é o argumento da função doSomething()
, pertence ao espaço para nome MyNamespace
. Portanto, ele olha para esse espaço para nome para localizar a declaração de doSomething()
.
Qual é a vantagem da pesquisa Koenig?
Como o exemplo de código simples acima demonstra, a pesquisa Koenig oferece conveniência e facilidade de uso ao programador. Sem a pesquisa de Koenig, haveria uma sobrecarga no programador, para especificar repetidamente os nomes totalmente qualificados ou, em vez disso, usar várias using
declarações -.
Por que as críticas à pesquisa de Koenig?
O excesso de confiança na pesquisa de Koenig pode levar a problemas semânticos e, às vezes, pegar o programador desprevenido.
Considere o exemplo de std::swap
, que é um algoritmo de biblioteca padrão para trocar dois valores. Com a pesquisa de Koenig, seria preciso ter cuidado ao usar esse algoritmo, porque:
std::swap(obj1,obj2);
pode não mostrar o mesmo comportamento que:
using std::swap;
swap(obj1, obj2);
Com o ADL, qual versão da swap
função é chamada dependeria do espaço para nome dos argumentos passados para ele.
Se existe um espaço de nomes A
e se A::obj1
, A::obj2
e A::swap()
existem, em seguida, o segundo exemplo irá resultar em uma chamada para A::swap()
, que pode não ser o que o usuário queria.
Além disso, se por algum motivo tanto A::swap(A::MyClass&, A::MyClass&)
e std::swap(A::MyClass&, A::MyClass&)
são definidos, em seguida, o primeiro exemplo chamará std::swap(A::MyClass&, A::MyClass&)
mas o segundo não irá compilar, porque swap(obj1, obj2)
seria ambíguo.
Curiosidades:
Por que é chamado de "pesquisa Koenig"?
Porque foi desenvolvido pelo ex-pesquisador e programador da AT&T e Bell Labs, Andrew Koenig .
Leitura adicional:
1 A definição da pesquisa de Koenig é a definida no livro de Josuttis, The C ++ Standard Library: A Tutorial and Reference .