2012-06-04 5 views
0

내가 클래스 정의/선언 내에서 공용 멤버 함수 템플릿을 전문으로하려고 :클래스 내에서 멤버 함수 템플릿을 특수화 할 수없는 이유는 무엇입니까?

#include <iostream> 

class surfaceMesh 
{ 
    public: 
     // Uncomment for Version 0 and 1 
     class AREA_AVERAGE {}; 
     class ANGLE_AVERAGE {}; 

     template<class Average> 
     void vertexNormals() {} 

     // Uncomment: Version 0 
     //template<> 
     //void vertexNormals<AREA_AVERAGE>() 
     //{ 
      //std::cout << "AREA_AVERAGE" << std::endl; 
     //} 

     //template<> 
     //void vertexNormals<ANGLE_AVERAGE>() 
     //{ 
      //std::cout << "ANGLE_AVERAGE" << std::endl; 
     //} 


}; 

// Uncommend for version 1 
template<> 
void surfaceMesh::vertexNormals<surfaceMesh::AREA_AVERAGE>() 
{ 
    std::cout << "AREA_AVERAGE" << std::endl; 
}; 

template<> 
void surfaceMesh::vertexNormals<surfaceMesh::ANGLE_AVERAGE>() 
{ 
    std::cout << "ANGLE_AVERAGE" << std::endl; 
}; 


int main() 
{ 
    surfaceMesh m; 

    m.vertexNormals<surfaceMesh::AREA_AVERAGE>(); 
    m.vertexNormals<surfaceMesh::ANGLE_AVERAGE>(); 

    return 0; 
} 

버전 0의 경우, 오류는 다음과 같습니다

main.cpp:19: error: template-id ‘vertexNormals<mesh::AREA_AVERAGE>’ in declaration of primary template 
main.cpp:24: error: explicit specialization in non-namespace scope ‘class mesh’ 
main.cpp:25: error: template-id ‘vertexNormals<mesh::ANGLE_AVERAGE>’ in declaration of primary template 
main.cpp:25: error: ‘void mesh::vertexNormals()’ cannot be overloaded 
main.cpp:19: error: with ‘void mesh::vertexNormals()’ 

버전 1 컴파일 및 실행됩니다. 물론, 보통 클래스 선언과 정의를 분리하려고합니다. 그러나 이것이 실제로 일어나는 이유를 알고 싶습니다.

또한 인터페이스를 특수화하는 좋은 방법입니까? 다른 옵션은 AREA_AVERAGE 또는 ANGLE_AVERAGE의 객체를 가져 오기 위해 vertexNormals 함수를 오버로드하는 것입니다. 그러나이 함수는 어떤 유형의 함수를 사용할 것인지를 알려주는 유형이며 인스턴스화하지 않아야하므로 템플릿을 사용하면 ' 올바른 선택처럼.

+0

기능 템플릿을 부분적으로 특수화 할 수 없습니다 (클래스 외부에있는 것은 전공 분야입니다). –

+0

놀랍게도 Visual Studio 2010의 버전 0은 – weidi

+0

@ n.m에서 컴파일됩니다. 고마워. 고마워. – tmaric

답변

4

클래스 내의 멤버 함수 템플릿을 특수화 할 수없는 이유는 무엇입니까?

이것은 C++ 표준에 의해 정의 된 규칙이므로. 표현 static_cast<Average*>(0)의 올바른 과부하를 선택하도록 컴파일러에 도움이

class surfaceMesh 
{ 
    public: 
     // Uncomment for Version 0 and 1 
     class AREA_AVERAGE {}; 
     class ANGLE_AVERAGE {}; 

     template<class Average> 
     void vertexNormals() 
     { 
      //invoke the function overload 
      vertexNormals(static_cast<Average*>(0)); 
     } 
private: 
     //make the overloads private, so client will not call them! 
     void vertexNormals(AREA_AVERAGE *) 
     { 
      std::cout << "AREA_AVERAGE" << std::endl; 
     } 
     void vertexNormals(ANGLE_AVERAGE*) 
     { 
      std::cout << "ANGLE_AVERAGE " << std::endl; 
     } 
}; 

유형 : 당신이 원하는에 관해서는

는 더 나은 방법으로 기능 과부하보다는 기능의 전문화를 사용하는 것입니다.

+0

O.K.하지만 기본 포인터를 사용하지 않아야하며 명시 적 클린업을 수행해야합니까? 또한 이것은 클라이언트가 다른 메소드들 사이에서 구별하기 위해 사용 된 평균화 유형의 실제 객체를 전달해야한다는 것을 의미하지는 않습니까? – tmaric

+1

@ tomislav-maric : 과부하를 호출 할 때 ** ** 할당 * 메모리가 아닙니다. 당신은'static_cast (0)'을 NULL로 사용하고 있지만이 표현식은 컴파일러를 돕는 * type *을 가지고 있습니다. – Nawaz

+0

@ tomislav-maric : 또한 과부하는 '비공개'입니다. 그래서 클라이언트는 함수 템플릿만을 호출 할 것이고, 함수 템플릿은'private' 오버로드를 호출합니다. – Nawaz

관련 문제