標籤:模板 提取 github calling stdio.h log ret amd 協助
Callable對象,是任何可以調用的東西。函數指標,函數,重載了operator()的對象,lamda
#include <iostream>#include <stdlib.h>#include <stdio.h>#include <functional>struct S{ int f1(char c){ std::cout << "S::f1 called\n"; } void operator()(char c){ std::cout << "S::operator() called\n"; }};int main(){ int (S::*fptr)(char c) = &S::f1; S obj; (obj.*fptr)(‘a‘); S* pobj = &obj; (pobj->*fptr)(‘a‘); obj(‘a‘);}
在模板編程實踐中,經常做調用轉寄,例如:
template< class Callable, typename ... Args>void dosomething( Callable f, Args... args){ f(args...); }void foo(char c){ std::cout << "foo called\n" ;}int main(){ dosomething(foo,‘c‘); //調用了 foo(‘c‘);}
但是,F(args...)只能應付普通函數,和重載operator()的對象。如果F是函數指標,就掛了。std::invoke就是一個utility類,協助解決這個大問題的。
template< class Callable, typename ... Args>void dosomething( Callable f, Args... args){ //f(args...); //應用範圍太窄, 對於成員函數指標,需要 (arg1.*f)(args...); 其中,arg1應從args中提取首個參數 std::invoke(f,args...); //ok 已經處理好一切}void foo(char c){ std::cout << "foo called\n" ;}int main(){ int (S::*fptr)(char c) = &S::f1; S obj; dosomething(fptr, obj, ‘a‘);}
參考:
//https://kelvinh.github.io/blog/2014/03/27/cpp-tutorial-pointer-to-member-function/
https://stackoverflow.com/questions/46388524/when-to-use-stdinvoke-instead-of-simply-calling-the-invokable
std::apply功能上類似std::invoke,Callable參數由tuple提供:
#include <iostream>#include <functional>int add(int a,int b){ return a+b;}int main(){ std::cout << std::apply(add, std::make_pair(1, 2)) << ‘\n‘;}
參考:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0376r0.html
C++ invoke apply visit