>백엔드 개발 >C++ >명시적으로 인스턴스화된 함수 템플릿에서 ADL(인수 종속 조회)이 실패하는 이유는 무엇입니까?

명시적으로 인스턴스화된 함수 템플릿에서 ADL(인수 종속 조회)이 실패하는 이유는 무엇입니까?

DDD
DDD원래의
2024-12-11 04:20:10571검색

Why Does Argument Dependent Lookup (ADL) Fail with Explicitly Instantiated Function Templates?

ADL 및 함수 템플릿 조회

함수 템플릿은 C 프로그래밍에서 중요한 역할을 하며 코드 재사용과 일반 기능을 가능하게 합니다. 그러나 특정 네임스페이스에서 함수 템플릿을 찾기 위해 ADL(인수 종속 조회)을 사용할 때 미묘한 제한이 발생합니다.

이 문제는 다음 코드에 설명된 것처럼 명시적인 템플릿 인수를 사용하여 함수 템플릿을 호출하려고 할 때 나타납니다. snippet:

namespace ns {
    struct foo {};
    template<int i> void frob(foo const&amp;) {}
    void non_template(foo const&amp;) {}
}

int main() {
    ns::foo f;
    non_template(f); // This is fine.
    frob<0>(f); // This is not.
}

이 실패의 이유는 C 표준의 특정 조항에서 비롯됩니다. C 표준 03 14.8.1.6에 따라 호출 시점에 해당 이름의 함수 템플릿이 표시되지 않는 한 명시적 템플릿 인수를 사용하여 함수 템플릿을 호출할 때 ADL이 적용되지 않습니다.

위의 예에는 다음이 있습니다. frob<0>(f)일 때 현재 범위에 frob라는 이름의 함수 템플릿이 표시되지 않습니다. 호출됩니다. 따라서 ADL이 트리거되지 않고 컴파일러가 원하는 함수 템플릿을 찾지 못합니다.

이 제한을 우회하려면 아래와 같이 함수 템플릿 앞에 네임스페이스를 명시적으로 지정할 수 있습니다.

ns::frob<0>(f);

이 경우 함수 템플릿이 포함된 네임스페이스에서 직접 호출되므로 ADL이 필요하지 않습니다.

다음 코드 예제에서는 함수를 사용하는 ADL의 동작을 자세히 보여줍니다. 템플릿:

namespace A {
  struct B { };
  template<int X> void f(B);
}
namespace C {
  template<class T> void f(T t);
}
void g(A::B b) {
  f<3>(b);    //ill-formed: not a function call
  A::f<3>(b); //well-formed
  C::f<3>(b); //ill-formed; argument dependent lookup
              // applies only to unqualified names
  using C::f;
  f<3>(b);    //well-formed because C::f is visible; then
              // A::f is found by argument dependent lookup
}

이 예에서 함수 템플릿 f는 네임스페이스 A와 C 모두에 정의됩니다. 호출 f<3>(b); 만들어지면 컴파일러는 먼저 현재 범위를 확인하고 눈에 보이는 f 템플릿을 찾지 않습니다. 그런 다음 ADL이 적용되지만 f는 정규화되지 않은 이름이므로 다른 네임스페이스에서 함수 템플릿을 찾을 수 없습니다.

네임스페이스 C에서 템플릿을 호출하려면 C::f 또는 지시문을 사용하여 이름을 명시적으로 한정해야 합니다. 코드에 표시된 대로

위 내용은 명시적으로 인스턴스화된 함수 템플릿에서 ADL(인수 종속 조회)이 실패하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.