1. 程式人生 > >C++ invoke apply visit

C++ invoke apply visit

som turn 如果 OS lam fun 例如 ack paper

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