2013-07-19 2 views
6

C++은 비 형식 템플릿 매개 변수가 함수 포인터, 유형을 포함하여 포인터가 될 수있게합니다. 나는 최근에 question에게 이것이 무엇에 유용한지를 물었고, 이것은 후속 조치 one of the answers입니다.함수 포인터 템플릿 매개 변수의 값을 추론하는 방법이 있습니까?

함수 포인터 템플릿 매개 변수의 을 해당 함수 포인터 인 함수 인수에서 추론 할 수 있습니까? 예 :

using VoidFunction = void(*)(); 

template <VoidFunction F> 
void templ(VoidFunction); 

... 

void func(); // a VoidFunction 

... 

templ<func>(func); // works, but I have to specify the template parameter explicitly 
templ(func);  // <-- I would like to be able to do this 

이 추론을 수행 할 수있는 방법이 있습니까? 컴파일러 구현 자의 관점에서 함수 인수가 컴파일 타임에 코드의 함수로 해석 될 수있는 한 기술적으로 가능합니다.

이 문제에 대한 궁금증이 있다면 this answer 아래의 설명, 특히 std::bind()의 구현을위한 가능한 최적화를 참조하십시오.

EDIT : templ<func>()처럼 함수 인수를 제거하고 템플릿 인수를 사용할 수 있다는 것을 알고 있습니다. 함수 인수에 추가하는 유일한 목적은 템플릿 인수를 전달하지 않아도되도록하는 것입니다.

template <typename Function, Function F> 
void templ(/* something */); 

을 다음

templ(func); 

또는

를 호출 할 수 :

내가 정말 원하는 것을 추측도 같이 함수 포인터의 유형을 추론하는 것입니다
templ<func>(); 

및 형식과 값을 모두 단일에서 추론해야합니다 함수 포인터에 대한 언급.

희망은 지금 더 의미가 있습니다.

+0

의 전체 템플릿 인수 목록을 작성하는 것을 피하기 위해, 오직 사용자 편의를 위해서만 여기에 사용되는

template<typename T, T value> struct NonType {}; template<typename T, T value> void f(NonType<T, value>) { } void g(); struct A { void f(); int m; }; int i; #define MAKE_NONTYPE(value) NonType<decltype(value), (value)>() int main() { f(MAKE_NONTYPE(0)); // NonType<int, 0> f(MAKE_NONTYPE(&g)); // NonType<void(*)(), &g> f(MAKE_NONTYPE(&A::f)); // NonType<void(A::*)(), &A::f> f(MAKE_NONTYPE(&A::m)); // NonType<int A::*, &A::m> f(MAKE_NONTYPE(&i)); // NonType<int*, &i> } 

주? 예를 들어, 이렇게 할 수 있습니다 :'template void foo (std :: size_t i) {int arr [N];/* fill */return arr [i];}'. 이 추론을 할 수있을 때 필자가 템플릿 인수를 잊어 버린다면 분명히 오류를 원할 것입니다. – chris

+0

생각해 보니 왜 함수 인수로 전달되어야하는지 이해할 수 없습니다. 'templ ();'충분하지 않습니까? – chris

+0

@chris : 맞아, 제 질문은 서면으로별로 의미가 없었습니다. 제발 제 편집을 참조하십시오. – HighCommander4

답변

2

함수의 템플릿 인수는 함수의 템플릿 매개 변수 유형에서 추론됩니다. 템플릿 인수는 해당 형식이 허용 된 형식 중 하나 일 때만 형식에서 추론 할 수 있습니다. 허용되는 형태

템플릿 인수는 여러 상황에서 도출 될 수 temp.deduct.type]에 명시되어 있지만, 각각의 경우에 템플릿 파라미터 (P를 호출)의 관점에서 지정되는 유형 비교 실제 형식 (A이라고 함)을 사용하고 P이 될 템플릿 인수 값 (형식 매개 변수의 형식, 형식이 아닌 매개 변수의 값 또는 템플릿 매개 변수의 서식 파일)을 찾으려고 시도하면, 추론 된 값을 대체 한 후 (A으로 추측), A과 호환됩니다.PA 다음 양식 중 하나가있는 경우

템플릿 형식 인수 T, 템플릿의 템플릿 인수 TT 또는 템플릿 비 타입 인수 i는 추론 할 수 있습니다

T 
cv-list T 
T* 
T& 
T[integer-constant] 
template-name (where template-name refers to a class template) 
type(*)(T) 
T(*)() 
T(*)(T) 
T type::* 
type T::* 
T T::* 
T (type::*)() 
type (T::*)() 
type (type::*)(T) 
type (T::*)(T) 
T (type::*)(T) 
T (T::*)() 
T (T::*)(T) 
type[i] 
template-name&lti> (where template-name refers to a class template) 
TT<T> 
TT<i> 
TT<>

(T) 적어도 하나의 인수 유형이 T을 포함하는 인수 목록을 나타내며 ()은 매개 변수가 T을 포함하는 인수 목록을 나타냅니다. 마찬가지로 <T>은 하나 이상의 인수에 T이 포함 된 템플릿 인수 목록을 나타내며 <i>은 템플릿 인수 목록을 나타내며 적어도 하나의 인수에는 i이 포함되고 <>에는 T 또는 i이 포함되지 않은 템플릿 인수 목록을 나타냅니다.

만 비 형 템플릿 인자를 고려하여, 적절한 형태 i 포함하는 것들이다 :

type[i] 
template-name&lti> (where template-name refers to a class template) 
TT<i>

따라서,이 함수의 인수의 값으로부터 직접 값을 도출하는 것은 불가능을 함수 포인터. 그러나 이며 함수 매개 변수에 지정된 양식 중 하나가 있으면 비 형식 템플리트 인수의 값을 추론 할 수 있습니다.

다음 코드는 NonType이라는 클래스 템플릿에서 비 형식 템플릿 인수 값을 줄 바꿈으로써이 문제를 해결합니다. f의 매개 변수는 template-name<i>의 형식으로되어있어 형식이 아닌 템플릿 인수의 값을 추론 할 수 있습니다. decltypeMAKE_NON_TYPE 매크로가 어떻게 그것을 추론 할 수 NonType

관련 문제