北大黄雨松同学的插件代码的又一个知识点:传递参的统一方式

/**
* 传递参数的统一方式,此方式可以用于北太天元插件的开发。
*/
#include <cstdlib>
#include <iostream>
#include <typeinfo>
#include <utility>
#include <array>
#include <vector>
using namespace std;
namespace ParseParams {
template <class _T>
class FunTrait;
template <typename R, typename... Args>
class FunTrait<R(Args...)>{
public:
static constexpr size_t n_args = sizeof...(Args);
public:
int required_params;
std::array<void *, n_args> passed_args_ptr;
//变量类型函数句柄, 变量名是decorated_func
R(*decorated_func)
(Args...);
public:
FunTrait(R (*func)(Args...), int num_required = 0){
decorated_func = func;
required_params = num_required;
}
template <size_t... I>
R eval_impl(std::index_sequence<I...>){
std::cout<<"需要的参数个数是 = " << required_params << std::endl;
return decorated_func((Args)passed_args_ptr[I]...);
}
R eval(){
return eval_impl(std::make_index_sequence<n_args>());
}
void check_in_args_type(const std::vector<void *> & a){
for(size_t i=0; i<n_args; i++)
passed_args_ptr[i] = a[i];
}
};
}
double f(){
std::cout<<" f is a function "<<std::endl;
return 1.0;
}
double g(const int * j){
std::cout<<" *j = "<< *j<<std::endl;
return (double)(*j);
}
char h(const int *j , const std::string *str ){
std::cout<<" *j = "<<*j << std::endl;
std::cout<<" *str = "<<*str << std::endl;
std::cout<<" (*str)[*j] = "<<(*str)[*j]<< std::endl;
return (*str)[*j];
}
int main(){
using namespace ParseParams;
typedef FunTrait<decltype(f)> FT;
//typedef FunTrait<double()> FT;
FT t(f,0);
t.eval();
FunTrait<decltype(g)> s(g,1);
int j = 4;
const std::vector<void *> s_in_args ={(void *)&j};
s.check_in_args_type(s_in_args);
s.eval();
FunTrait<decltype(h)> q(h,2);
std::string str = "LOVE";
int i = 1;
const std::vector<void *> q_in_args ={(void *)&i, (void *)&str};
q.check_in_args_type(q_in_args);
q.eval();
return 0;
}