인수 종속 조회(Argument-Dependent Lookup, ADL)는 함수 호출 표현식에서 한정되지 않은(unqualified) 함수 이름을 찾는 규칙입니다. Koenig 조회(Koenig Lookup)라고도 불리며, C++의 오버로드 해석 과정에서 중요한 역할을 합니다.
여기서 말하는 함수 호출 표현식에는 연산자 오버로딩에 의해 암묵적으로 발생하는 함수 호출도 포함됩니다.
인수 종속 조회의 동작 원리
일반적인 한정되지 않은 이름 조회(unqualified name lookup)가 검사하는 범위(scope)와 네임스페이스에 더해, ADL은 함수 인수의 타입이 속한 네임스페이스까지 추가로 검색합니다.
이 덕분에 다른 네임스페이스에 정의된 연산자나 함수를 별도의 using 선언 없이 자연스럽게 사용할 수 있습니다. 대표적인 예가 바로 std::cout과 함께 사용하는 <<, >> 연산자입니다.
예제 코드
namespace MyNamespace {
class A {};
void f(A &a, int i) {}
}
int main() {
MyNamespace::A a;
f(a, 0); // MyNamespace::f 호출
}예제 설명
위 코드에서 f라는 함수 이름은 전역 범위에는 존재하지 않지만, 컴파일러는 정상적으로 이 코드를 컴파일합니다. 그 이유는 함수 호출 시 전달된 인수 a의 타입 MyNamespace::A가 속한 네임스페이스인 MyNamespace까지 조회 범위가 확장되기 때문입니다.
즉, f(a, 0) 호출은 인수 a에 의존하여 MyNamespace::f를 찾아내게 됩니다.
실전 활용: std 네임스페이스와 스트림 연산자
같은 원리가 std 네임스페이스에도 적용됩니다. 다음 코드를 살펴보겠습니다.
#include <iostream>
int main() {
std::cout << "Hello, ADL!" << std::endl;
}std::cout 객체에 << 연산자를 적용하면, 컴파일러는 std 네임스페이스 내부에서 해당 연산자 오버로드를 찾습니다. 만약 ADL이 없다면 매번 std::operator<<처럼 명시적으로 한정하거나 using namespace std;를 선언해야 했을 것입니다.
정리
- ADL은 한정되지 않은 함수 이름을 조회할 때, 인수 타입이 속한 네임스페이스를 추가로 검색하는 규칙입니다.
- 오버로드된 연산자의 암묵적 함수 호출에도 동일하게 적용됩니다.
cout,cin,endl등과 함께 쓰이는<<,>>연산자가std네임스페이스에서 정상적으로 동작하는 핵심 메커니즘입니다.