关于变参函数指针以及变参Function模板

1、首先要了解函数指针以及C++11的function实现:

//对于函数指针有如下代码:
//1. 定义一个函数指针
typedef bool (*pFun)(int,int);
//2.有函数实体1
bool checkBigger(int a,int b)
{
    if (a>b)
        return true;
    else
        return false;
}
//3.有函数实体2
bool checkSmaller(int a,int b)
{
    if (a<b)
        return true;
    else
        return false;
}
int main()
{
    //创建指针1
    pFun pBigger=checkBigger;
    //创建指针2
    pFun pSmaller = checkSmaller;
    std::cout<<"pBigger(1,2):"<<(*pBigger)(1,2)<<std::endl;
    std::cout<<"pSmaller(1,2):"<<(*pSmaller)(1,2)<<std::endl;
}
 对应的C++11function实现
std::function<bool(int,int)> fBigger=checkBigger;
std::cout<<"fBigger:"<<fBigger(1,2)<<std::endl;

2、实现变参函数

     2.1 C风格的变参函数
double getSum(int NumofPara, ...)
{
	int i = 0;							//用于for循环 
	double sum = 0.0;					//用于求和 

	va_list pointer;					//新建一个va_list类型的指针 

	va_start(pointer, NumofPara);		//初始化指针,指针指向确定 
	
	for( i = 0; i < NumofPara; i++ )
	{
		sum += va_arg(pointer, double);	//通过va_arg函数来访问可变参数,返回类型为double 
	}									//同时,每次va_arg函数结束后,va_list指针指向下一位 
	
	va_end(pointer);					//终结指针,释放内存 
	
	return sum;

	//P.S. 有个问题要注意一下,在main函数里调用的时候,应该写成getSum(3, 7.0, 8.0, 9.0),否则得到的可能是0。
}
typedef double(*pgetSum)(int, ...);

int main()
{
    pGetSum = getSum;
	std::cout<<(*pGetSum)(2, 1.0, 2.0);
}

C语言风格的变参,最大的问题就在于无法检查变参的实际种类,例如对于上面的例子,如果输入

pGetSum(2,1,2),输出的结果就可能是0;C++11就提供变参function:

       2.2、C++变参 function

#include <list>  
#include <functional>  
  
template<typename... Args>  
class Fns  
{  
private:  
  
    std::list<std::function<void(Args...)> > _calls;  
  
public:  
  
    virtual ~Fns()  
    {  
        _calls.clear();  
    }  
  
    void connect(std::function<void(Args...)> fct)  
    {  
        _calls.push_back(fct);  
    }  
  
    template<typename Object>  
    void connect(Object* object, void (Object::*method)(Args...))  
    {  
        _calls.push_back([object,method](Args... args){(*object.*method)(args...);});  
    }  
  
    template<typename Object>  
    void connect(Object* object, void (Object::*method)(Args...) const)  
    {  
        _calls.push_back([object,method](Args... args){(*object.*method)(args...);});  
    }  
  
    template<typename Object>  
    void connect(const Object* object, void (Object::*method)(Args...) const)  
    {  
        _calls.push_back([object,method](Args... args){(*object.*method)(args...);});  
    }  
  
    void emit(Args... args)  
    {  
        for(auto call : _calls)  
            call(args...);  
    }  
};  
#include <cstdio>
#include "Signal.hpp"
 
class Foo
{
public:
 
	void bar(int x, int y)
	{
		printf("Foo::bar(%d, %d)\n", x, y);
	}
};
 
void foobar(int x, int y)
{
	printf("foobar(%d, %d)\n", x, y);
}
 
int main(void)
{
	Foo foo;
	Fns<int, int> s;
 
	// Connect a function
	s.connect(foobar);
	// Connect a class method
	s.connect(&foo, &Foo::bar);
	// Create and connect some lambda expression
	s.connect([&foo](int x, int y){ 
		printf("lambda::"); foo.bar(x, y); 
	});
	// Emit the signal !
	s.emit(4, 2);
	getchar();
	return 0;
}

参考资料:

1、 char *(*c[10])(int **p);_junlon2006的博客-CSDN博客

2、C语言可变参数函数_初探_谁还不是个程序猿的博客-CSDN博客_c语言可变参数函数

3、C++11 std::bind std::function 变参函数_同皆无穷小的博客-CSDN博客_std::bind 可变参数

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陶醉鱼

感觉写的不错就给个打赏哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值