인수에 의존하는 이름 검색
Argument-dependent name lookupC++ 프로그래밍 언어에서는 함수 호출에 지정된 인수 유형에 따라 인수 의존형 검색(ADL)[1] 또는 인수 의존형 이름 검색이 미수식 함수 이름에 적용됩니다.이 행동은 종종 Andrew Koenig가 [2]발명가는 아니지만 기인하기 때문에 Koenig 룩업으로도 알려져 있습니다.
인수에 의존한 룩업에서는, 통상의 룩업시에 고려되지 않는 다른 네임스페이스를 검색할 수 있습니다.검색되는 네임스페이스의 세트는 함수 인수의 유형에 따라 달라집니다.구체적으로는 ADL 프로세스 중에 검출되어 함수명의 해결을 위해 고려되는 선언 세트는 통상적인 룩업에 의해 검출된 선언과 함수 인수의 유형과 관련된 네임스페이스 세트를 조사함으로써 검출된 선언의 결합입니다.
예
ADL의 예는 다음과 같습니다.
네임스페이스 NS { 학급 A {}; 무효 f(A& a, 인트 i) {} } // 네임스페이스 NS 인트 주된() { NS::A a; f(a, 0); // NS::f를 호출합니다. } 함수는 네임스페이스 NS에도 없고 네임스페이스 NS에도 없습니다만, 함수는 함수 호출문의 실제 파라미터의 선언된 유형에 의해 검출됩니다.
C++ 표준 라이브러리의 일반적인 패턴은 이 방법으로 검출되는 오버로드 연산자를 선언하는 것입니다.예를 들어 이 간단한 Hello World 프로그램은 ADL이 없으면 컴파일되지 않습니다.
#실패하다 <iostream> #실패하다 <문자열> 인트 주된() { 표준::스트링 스트레이트 = '헬로 월드'; 표준::외치다 << > 스트레이트; } 사용.<<콜링과 동등합니다.operator<<를 제외하고std::한정자단, 이 경우 연산자 <<>의 과부하로 인해string에 있습니다.stdADL을 사용하려면 , 네임스페이스를 사용해야 합니다.
다음 코드는 ADL이 없어도 동작합니다(이 코드는 ADL에 적용됩니다).
#실패하다 <iostream> 인트 주된() { 표준::외치다 << > 5; } 정수의 출력 연산자가 의 멤버 함수이기 때문에 동작합니다.std::ostreamclass, 이것은 의 유형입니다.cout따라서 컴파일러는 이 스테이트먼트를 다음과 같이 해석합니다.
표준::외치다.교환입니다.<< >(5); 일반 조회 중에 해결할 수 있습니다.단, 예를 들어,const char *과부하operator<<의 비멤버 함수입니다.std따라서 올바른 검색을 위해서는 ADL이 필요합니다.
/*는 인수 유형 std::cout */에서 파생된 ADL을 사용하여 제공된 문자 문자열을 올바르게 인쇄합니다. 교환입니다.<< >(표준::외치다, "안녕하세요") /*가 오퍼레이터의 오스트림멤버 함수를 호출합니다< void const*, 그러면 문자 문자열의 내용이 아닌 제공된 문자 문자열의 주소가 인쇄됩니다. */ 표준::외치다.교환입니다.<< >("안녕하세요") 그std네임스페이스 오버로드 비멤버operator<<문자열을 처리하는 함수도 다른 예입니다.
/*연산자<(std::cout, str).컴파일러는 str 파라미터의 type std::string 및 std::cout */을 위해 ADL을 사용하여 std 네임스페이스를 검색합니다. 표준::외치다 << > 스트레이트; Koenig가 개인 [2]메모에서 지적했듯이 ADL이 없으면 컴파일러는 찾을 수 없다는 오류를 나타낼 것입니다.operator<<스테이트먼트에 의해 검출되는 것을 명시적으로 명기하고 있지 않기 때문에std네임스페이스.
인터페이스
ADL에 의해 발견된 함수는 클래스 인터페이스의 일부로 간주됩니다.C++ Standard Library에서는 몇 가지 알고리즘이 수식되지 않은 콜을 사용하여swap내부로부터std네임스페이스.그 결과, 범용은std::swap다른 것을 찾을 수 없는 경우 함수가 사용되지만 이러한 알고리즘이 서드파티 클래스에서 사용되는 경우Foo를 포함하는 다른 네임스페이스에 있습니다.swap(Foo&, Foo&)그 과부하로swap사용됩니다.
비판
ADL을 사용하면 클래스 외부에서 정의된 함수가 해당 클래스의 인터페이스의 일부인 것처럼 동작하는 것이 실용적이지만 네임스페이스가 덜 엄격해지기 때문에 필요하지 않은 경우 완전 수식 이름을 사용해야 할 수 있습니다.예를 들어 C++ 표준 라이브러리는 정규화되지 않은 콜을 광범위하게 사용하여std::swap2개의 값을 바꿉니다.이 아이디어는 다음과 같이 자신의 버전을 정의할 수 있다는 것입니다.swap표준 라이브러리 알고리즘 내에서 사용됩니다.바꿔 말하면, 의 행동은
네임스페이스 N { 구조 A {}; } // 네임스페이스 N A a; A b; 표준::바꾸다(a, b); 행동과 같을 수도 있고 아닐 수도 있다
사용. 표준::바꾸다; 바꾸다(a, b); (어디서)a그리고.b종류N::A)이유는 만약N::swap(N::A&, N::A&)위의 예 중 두 번째는 호출하지만 첫 번째는 호출하지 않습니다.게다가, 만약 어떤 이유로든 둘 다N::swap(N::A&, N::A&)그리고.std::swap(N::A&, N::A&)정의되어 있는 경우 첫 번째 예에서는std::swap(N::A&, N::A&)두 번째는 컴파일되지 않습니다.swap(a, b)애매할 것 같아요.
일반적으로 ADL에 지나치게 의존하면 의미 문제가 발생할 수 있습니다.만약 하나의 도서관이 있다면,L1는, 에의 수식되지 않은 콜을 상정하고 있습니다.foo(T)하나의 의미와 다른 도서관을 가지기 위해L2다른 네임스페이스가 있을 것으로 예상하면 네임스페이스는 효용성을 잃게 됩니다.단, 만약L1예기하다L1::foo(T)하나의 의미를 가지다L2마찬가지로 경합은 발생하지 않습니다만,foo(T)완전한 자격을 갖추어야 한다(예:L1::foo(x)와는 반대로using L1::foo; foo(x);ADL이 방해가 되지 않도록 합니다.
레퍼런스
- ^ "Working Draft, Standard for Programming Language C++" (PDF). JTC1/SC22/WG21. 19 October 2005. Chapter 3.4.2 – Argument-dependent name lookup – p. 2. Archived from the original (PDF) on 14 December 2005. Retrieved 13 March 2012.
- ^ a b "A Personal Note About Argument-Dependent Lookup". 3 May 2012. Archived from the original on 17 March 2018. Retrieved 7 February 2014.
외부 링크
- 인수 의존형 룩업
- 클래스란 무엇입니까?– Herb Sutter의 인터페이스 원리
- 허브 서터의 네임스페이스와 인터페이스 원리
- 대니 칼레프의 네임스페이스가 싫은 이유
- "소중한 제안: Herb Sutter의 ADL 수정(리비전 2)"
