2012-07-31 4 views
14

템플릿 인수는 멤버 함수에 대한 포인터가 될 수있는 것으로 알려져 있습니다. 멤버 함수 포인터에 대한 템플릿 인수 차감

그래서 내가 쓸 수 있습니다 :

struct Bar 
{ 
    int fun(float x); 
}; 

template <int (Bar::*FUN)(float)> 
struct Foo 
{ /*...*/ }; 

typedef Foo<&Bar::fun> FooBar; 

그러나 무엇을 나는이 (가) Bar 유형 자체가 템플릿 인수가 되길 원한다면 : 이제

template <typename B, int (B::*FUN)(float)> 
struct Foo 
{ /*...*/ }; 

typedef Foo<Bar, &Bar::fun> FooBar; 

, 내가 그것을 사용할 때, 나는 쓸 필요가 Bar 두 번!

제 질문은 컴파일러가 자동으로 클래스 유형을 추론하도록 할 수 있습니까?

목적은 작업이입니다 :

typedef Foo<&Bar::fun> FooBar; 
typedef Foo<&Moo::fun> FooMoo; 

답변

5

아마 거기에 클래스 이름을 써야합니다. 그러나, 당신이 정말로 그것을 피하고 싶다면 당신은 매크로의 사악한 마법을 사용할 수 있습니다. 간단한 버전은 더 위험 :

#define TT(X) decltype(X), X 

template<typename T,T t> 
struct Foo 
{ /* ... */ }; 

struct Bar { 
    int fun(float) {} 
}; 

int main() { 
    Foo<TT(&Bar::fun)> f; 
} 

비 형 템플릿 매개 변수의 어떤 종류를 받아 들일 것입니다, 당신은 발생할 수있는 어려운 이해 Foo 구현은 포인터 - 투 - 회원과 함께 작동하는 경우 오류를. C++ 11 그래서 그들은 오래된 컴파일러와 함께 작동하지 않습니다 사용하는 이들 또한

template<typename T> struct member_ptr_traits; 

template<typename Class,typename Ret,typename... Args> 
struct member_ptr_traits<Ret (Class::*)(Args...)> 
{ 
    typedef Class class_type; 
    typedef Ret return_type; 
}; 

#define TT(X) member_ptr_traits<decltype(X)>::class_type , X 

template<typename T,int (T::*FUN)(float)> 
struct Foo 
{ /* ... */ }; 

struct Bar { 
    int fun(float) {} 
}; 

int main() { 
    Foo<TT(&Bar::fun)> f; 
} 

모두 :

은 조금 더 안전한 당신에게 클래스 이름을 알려주는 metafunction이 필요합니다 확인하십시오. 이 간단한 버전은 이전 typeof 또는 유사한 컴파일러 확장을 사용하도록 다시 작성할 수 있습니다. 더 안전한 버전을 다시 작성하려면 다양한 템플릿을 시뮬레이션해야합니다.

+0

사실,이 템플릿은 라이브러리 내부의 템플릿이기 때문에 오용의 위험이 없습니다. 어쨌든'member_ptr_traits'는 실제로'T' 타입이 필요하기 때문에 훌륭합니다. – rodrigo

7

간단한 답 :이 없을 없음.

문제는 typedef Foo<&Bar::fun> FooBar;이 작동하려면 템플릿에 형식이 아닌 인수가 하나 있어야하지만 서식 파일이 선언 될 때 해당 인수의 형식이 유효하지 않은 것입니다. 반면에 유형 공제는 템플리트의 인수에 적용되지 않습니다 (함수 템플리트의 인수에만 해당하지만 템플리트의 인수는 함수가 아닌 템플리트의 인수입니다).

+0

알기. 따라서 템플릿 기능을 수행하는 것도 불가능합니다. – rodrigo

+0

@rodrigo : 템플릿 인수를 포인터로 멤버로 사용하려는 경우. 질문은 멤버에 대한 포인터가 템플릿 인수가 될지, 아니면 추론 될 수있는 함수 인수가 될 수 있는지 여부입니다. –

+0

예, 중첩 템플릿을 인스턴스화하는 데 사용해야하므로 템플릿 인수가 필요합니다. 어쨌든, 통찰력을 주셔서 감사합니다. – rodrigo

관련 문제