C++ invoke apply

Callable對象,是任何能夠調用的東西。函數指針,函數,重載了operator()的對象,lamdahtml

#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');
}

在模板編程實踐中,常常作調用轉發,例如:ios

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類,幫助解決這個大問題的。git

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');
}

 參考:github

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-invokableapp

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';
}

 

另外還有一個將來的更強大的調用轉發函數:std:callspa

參考:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0376r0.html指針

相關文章
相關標籤/搜索