4

가능한 중복 :
Priority when choosing overloaded template functions in C++C++ 함수 오버로드 확인

템플릿 기반 기능은 나에게 종류의 다양한에서 작동하도록 편의를 제공합니다 :

template<typename T> void destroy(T* obj) { 
    delete obj; 
} 

하지만 어느 시점에서 나는 클래스 계층 구조에 대한 전문화를 원합니다. Y는 :

I, A는 정확한 유형 Base*을 전달하는 경우 의도 된 전문 기능이 호출 않았다
class Base { virtual void doSomething(); }; 
class Derived : public Base {}; 
void destroy(Base* obj) { 
    obj->doSomething(); 
    delete obj; 
} 

그러나 오버로드 확인의 규칙 대신 정전기 캐스트를 수행하는 일반 템플릿 버전을 선호하는 것 같다 내가 패스 Derived*에있는 경우 void detroy().

확실히 모든 가능한 파생 형식에 대해 모든 오버로드 된 함수를 만들 수 있지만 유지 관리가 쉽지 않습니다.

Visual C++ 2008을 사용하고 있는데 위와 같은 문제가 발생합니까?

+0

[C++에서 오버로드 된 템플릿 함수를 선택할 때 우선 순위] (http://stackoverflow.com/questions/1332678/priority-when-choosing-overloaded-template-functions) 스택 오버플로에서 같은 문제에 대한 깔끔한 대답을 발견했습니다. -in-c) –

+0

그러나 파괴 기능에 문제가 있습니다. 그것은 1D 배열 타입에 대해서도 호출 될 것이고, 정의되지 않은 동작 인 'delete []'대신에 'delete'를 수행 할 수 있습니다. – Chubsdad

+0

작전 본부는이 Q가 복제물로 폐쇄되어야한다고 인정합니다. –

답변

0

비주얼 C 같은 것은 없다 ++ 2009

당신은 다른 템플릿으로 함수를 전문으로 만 자료의 서브 타입에 맞게 SFINAE을 사용할 수 있습니다. 그러나 컴파일러가 두 번째 버전을 선호하는 이유를 모르겠다. 일반적으로 특수화는 어떤 방식 으로든 "더 나은"선택이되어야한다.

또는 SFINAE 및 도우미 특성 클래스를 사용하여 제네릭 버전이 Base의 서브 클래스와 일치하지 않도록 할 수 있습니다. 이 예가 필요한 경우, 물어보십시오.

물론 특수화는 표시되는 곳에서만 사용됩니다. 템플리트 함수는 항상 인라인이며, 호출자가 포함하는 헤더 파일에 있어야합니다.

5

모든 것이 동일하면 과부하 해결은 템플릿이 아닌 함수를 선호합니다. 그러나이 경우 모든 것이 동일하지 않습니다. Base*에 대한 오버로드를 일치 시키려면 derived-to-base 포인터 변환이 필요합니다. 함수 템플리트를 일치시키는 데 변환이 필요하지 않습니다. 따라서 함수 템플리트는 Derived*으로 선택됩니다.

"단순한"오류가 발생하기 쉬운 해결책은 함수를 호출하기 전에 Derived*Base*으로 변환하는 것입니다.

이론상 적어도 Ben이 말한 것처럼 SFINAE 방식을 사용할 수는 있지만 전문화 기능을 제공하는 모든 유형에 대해 일반 함수 템플릿을 명시 적으로 사용하지 않도록 설정해야합니다. 그렇지 않으면 과부화 모호성이 생길 수 있습니다. 이는 명백한 캐스트 방법보다 훨씬 유지 보수가 잘되고 오류가 발생하기 쉽습니다. (비록 여기에있는 누군가가 과부하 모호성을 극복하기위한 또 다른 방법을 알고 있을지 모르지만 나는 분명히 거기에 있는지 알고 싶어 할 것입니다.)