이 사실을 알게 된 것은 당연합니다. 우리 대부분은 처음에 그렇게합니다.
첫째 :
template<typename>
struct function_traits; // (1)
이것은 유형 (클래스 X, 구조체 Y, INT, 플로트, 표준 : : 문자열, 무엇이든) 인 하나의 템플릿 매개 변수가 템플릿 클래스의 일반적인 형태를 선언 . 현재 템플리트는 선언되지만 템플리트에는 특수화가 없으므로 클래스를 인스턴스화 할 수 없습니다. 심지어 기본 설정이 아닙니다.
둘째 :
template<typename ClassType,
typename ReturnType,
typename... Arguments>
struct function_traits<ReturnType(ClassType::*)(Arguments...) const> { // (2)
...
using result_type = ReturnType; // capture the template type into a typedef in the class namespace
};
이 T 어떤 반환 형식을 반환과 인수의 수를 소요하는 모든 클래스의 멤버 함수 포인터 템플릿 function_traits<typename T>
의 부분 특수화를 정의합니다. ReturnType
에는 템플릿 매개 변수가 할당되었으므로이 클래스의 정의가 해당 클래스를 유형으로 참조하여 멤버 함수 result_type
을 추론 할 수 있음을 의미합니다.
그러나 호출자가 호출 사이트에서 function_traits<&SomeClass::someFunction>
과 같이 완전한 함수 포인터를 지정해야하고 오버로드를 처리하는 것이 까다로울 수 있으므로이 단계에서는 특수화가 유용하지 않습니다.
이제 세번째 부분은 클래스 T
들어 function_traits<T>
가 function_traits<&T::operator()>
로부터 유도되어야한다는라는 '인터페이스'특성화한다. 템플릿 확장 이러한 특정 매치가 있으므로
template<typename T>
struct function_traits : public function_traits<decltype(&T::operator())> {};
// (3) Why here inheritance?
, 그것은 단지 호출 연산자 (operator()
)가 유형 확장한다. 기본 클래스는 두 번째 전문 분야의 반환 유형을 제공하므로이 템플릿은 호출 연산자가있는 모든 유형의 반환 유형을 캡처 할 수 있습니다. 이 클래스는 반환 형식을 캡처하는 실제 클래스에서 파생되므로 result_type
도이 클래스의 범위에 속합니다.
는 지금 우리가 쓸 수 있습니다 :
struct Foo {
int operator()();
};
using foo_ret = function_traits<Foo>::result_type;
그리고 foo_ret는 int
될 것입니다.
여전히 혼란 스럽습니까? 템플릿 프로그래밍의 첫 6 개월에 오신 것을 환영합니다.
두 가지 유형의 유형 (멤버 함수 포인터 유형 및 호출 연산자가있는 클래스 유형)에 부분적으로 특화된 클래스 템플릿입니다. 후자의 전문화는 단순히 전 (상속을 사용하여)의 관점에서 정의됩니다. –
모든 상속이 가상 소멸자 및 공용 동물에 관한 것은 아닙니다. 상속은 다양한 응용 프로그램과 함께 매우 일반적인 도구입니다. –
코드의 어떤 부분을 이해하지 못합니까? 그것은 키워드입니까, 키워드의 특정 용도입니까? 아직 템플릿 프로그래밍에 관한 튜토리얼을 읽었습니까? * 당신이 알고 있거나 이해하는 것은 무엇입니까? [질문하는 방법] –