단편 : 필요할 때마다 할 수 있으면 과부하.
Long story : C++은 전문화와 과부하를 매우 다르게 처리합니다. 이것은 예제를 통해 가장 잘 설명됩니다.
template <typename T> void foo(T);
template <typename T> void foo(T*); // overload of foo(T)
template <> void foo<int>(int*); // specialisation of foo(T*)
foo(new int); // calls foo<int>(int*);
이제 마지막 두 개를 바꾸어 봅시다.
template <typename T> void foo(T);
template <> void foo<int*>(int*); // specialisation of foo(T)
template <typename T> void foo(T*); // overload of foo(T)
foo(new int); // calls foo(T*) !!!
컴파일러는 전문화하기 전에 해상도를 오버로드합니다. 따라서 두 가지 경우 모두 과부하 해결은 foo(T*)
을 선택합니다. 그러나 두 번째 경우 int*
전문화 과정은 foo(T)
이 아닌 foo(T*)
의 전문화이기 때문에 첫 번째 경우에만 foo<int*>(int*)
을 찾습니다.
귀하는 std::swap
을 언급했습니다. 이것은 일을 훨씬 더 복잡하게 만듭니다.
표준은 std
네임 스페이스에 전문화를 추가 할 수 있다고 말합니다. 좋아요, 당신은 Foo
타입을 가지고 있고 퍼포먼스 스왑을 가지고 있습니다. 그러면 네임 스페이스에 swap(Foo&, Foo&)
을 전문으로합니다. 아무 문제 없습니다.
하지만 Foo
이 템플릿 클래스 인 경우 어떻게해야합니까? C++에는 함수의 부분적인 특수화가 없으므로 swap
을 특수화 할 수 없습니다. 유일한 선택은 오버로딩이지만 표준에서는 std
네임 스페이스에 오버로드를 추가 할 수 없다고 말합니다.
당신은이 시점에서 두 가지 옵션이 있습니다
자신의 네임 스페이스에 swap(Foo<T>&, Foo<T>&)
기능을 만들기를하고 ADL을 통해 발견됩니다 바랍니다. 표준 라이브러리가 std::swap(a, b);
처럼 스왑을 호출하면 ADL이 작동하지 않기 때문에 "희망"이라고 말합니다.
표준의 오버로드를 추가하지 말고 무시하는 부분은 무시하십시오. 솔직히 기술적으로 허용되지는 않지만 모든 현실적인 시나리오에서 작동 할 것입니다.
기억해야 할 점은 표준 라이브러리가 swap
을 전혀 사용하지 않는다는 것입니다. 대부분의 알고리즘은 std::iter_swap
을 사용하고 일부 구현에서는 살펴 보았지만 항상 std::swap
으로 전달하지는 않습니다.
이 좋은 예 선생님 – tenfour
...이 점을 지적했다 "나는 희망이 있기 때문에 말을"
기능 오버로드를 사용하여 비슷한 작업을 수행하려면, 당신은 함수 서명에 매개 변수를 추가해야 몇 년 전에 WG21에서 모든 표준 라이브러리 구현자는 알지 못합니다. – MSalters
멋진 답변, 정말 고마워요. –