2013-09-04 3 views
2

필자는 매개 변수로 펑터를 받아 들일 수있는 템플릿 함수를 작성하고 나중에 호출하려고했습니다.템플릿 함수의 std :: function

#include <iostream> 
#include <functional> 
using namespace std; 

template<typename R, typename... Args> 
R call(function<R(Args...)> fun, Args... args) 
{ 
    cout << "[email protected] " << __LINE__ <<endl; 
    return fun(args...); 
} 

int main() 
{ 
    cout << call(std::plus<int>(),1,2) <<endl; 
    return 0; 
} 

G ++ compplains : 다음과 같이 프로그램입니다

g++ -c -Wall -std=c++0x -I../include a.cpp -o a.o 
a.cpp: In function ‘int main()’: 
a.cpp:16:38: error: no matching function for call to ‘call(std::plus<int>, int, int)’ 
a.cpp:16:38: note: candidate is: 
a.cpp:7:3: note: template<class R, class ... Args> R call(std::function<_Res(_ArgTypes ...)>, Args ...) 
a.cpp:7:3: note: template argument deduction/substitution failed: 
a.cpp:16:38: note: ‘std::plus<int>’ is not derived from ‘std::function<_Res(_ArgTypes ...)>’ 
make: *** [a.o] Error 1 

내가 std::plus<int>()std::function<int(int,int)>으로 추론 할 수있는 가정을,하지만하지 않았다. 왜 그랬지? GCC는 gcc version 4.7.2 20120921 (Red Hat 4.7.2-2) (GCC)

답변

6

을 나는 표준을 가정 :: 플러스() 수 std :: 기능

아니,하지 수 추론 할 수있다 유형 std::plus<int>의 객체를 전달 했으므로 추론해야합니다.

std::function을 사용할 필요가 없습니다. 일반적으로 특정 서명으로 호출 할 수있는 다른 함수/함수 개체를 저장할 때 주로 사용합니다.

그걸로 call 함수는 std::function을 사용하지 않고 함수/함수 객체를 원래 유형을 추론하여 직접 수락 할 수 있습니다. 또한 매개 변수를 수락 할 때 완벽한 전달을 사용하고 함수/함수 객체에 인수로 전달할 때 std::forward을 사용할 수도 있습니다. 함수의 반환 형식을 반환 형식 call으로 사용해야합니다. C++ 11의 후행 반환 형식은 decltype입니다. @Jan Hudec이 무슨 항상 call 모든 통화에 동일하게 발생합니다 거기 commented, __LINE__는 어떤 기능을하는 통과함에 따라


LIVE CODE

#include <iostream> 
#include <functional> 
using namespace std; 

template<typename R, typename... Args> 
auto call(R fun, Args&&... args) -> decltype(fun(std::forward<Args>(args)...)) 
{ 
    cout << "[email protected] " << __LINE__ <<endl; 
    return fun(std::forward<Args>(args)...); 
} 

int main() 
{ 
    cout << call(std::plus<int>(),1,2) <<endl; 
    return 0; 
} 
.

+1

+1 '__LINE__'의 쓸데없는 점을 놓쳤습니다. _all_ 호출에 _same_ 행을 인쇄합니다. –

+1

나는 강조하기를 원한다 : "** std :: function' **"을 사용할 필요가 없다. 'std :: function'이 과용 될 것 같습니다. –

2

템플릿 인수를 추론 할 수 없습니다.

그래서 같이 함수 서명을 변경하는 것이 좋습니다 :

template<typename F, typename... Args> 
auto call(F fun, Args... args) 
    -> decltype(fun(args...)) 
0

대부분의 암시 적 변환은 템플릿 인수를 추론 할 때 고려되지 않습니다. 확실히 사용자 정의 된 것은 아닙니다. 따라서 plusfunction으로 변환 될 수 있더라도 차이는 없습니다.

관련 문제