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的博客-优快云博客
2、C语言可变参数函数_初探_谁还不是个程序猿的博客-优快云博客_c语言可变参数函数
3、C++11 std::bind std::function 变参函数_同皆无穷小的博客-优快云博客_std::bind 可变参数