1 std::function
函数模板形式:
template <class T>函数;//未定义
模板<class Ret,class ... Args> class function <Ret(Args ...)>;
1.1 函数模板说明
std::function是一个函数包装器模板,该函数包装器模板可以包装任意可以调用的元素,其包装器的类型只依赖于其调用特征,而不依赖于可调用元素自身的类型。
std::function可包装下列可调用元素类型:
- 函数
- 函数指针
- 类成员函数
- 任意类型的函数可调用对象(比如重载了operator()操作符并且拥有函数闭包的函数体对象)
- ...
std::function对象可被拷贝和转移,并且可以使用指定的调用特征来直接调用目标元素。
当std::function对象未包裹任何实际的可调用元素,调用该std::function对象将抛出std::bad_function_call异常。
1.2 模板参数说明
- T : 通用类型,但实际通用类型模板并没有被定义,只有当T的类型为形如Ret(Args...)的函数类型才能工作;
- Ret :调用函数返回值的类型;
- Args:函数参数类型,对于指向成员函数的指针,第一个参数应该是指向该成员函数的引用或者对象。
2 std::function可包装的几种函数形式总结
2.1 包装普通函数和静态函数
2.1.1 非模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
int Add(int a, int b)
{
std::cout << "普通函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
static int StaticAdd(int a, int b)
{
std::cout << "静态函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
int main()
{
// 1 普通函数
std::function<int(int, int)> addFunc1 = Add;
addFunc1(1, 2);
// 2 普通函数指针
std::function<int(int, int)> addFunc2 = &Add;
addFunc2(3, 4);
// 3 静态函数
std::function<int(int, int)> staticAddFunc1 = StaticAdd;
staticAddFunc1(5, 6);
// 4 静态函数指针
std::function<int(int, int)> staticAddFunc2 = &StaticAdd;
staticAddFunc2(7, 8);
getchar();
return 0;
}
2.1.2 模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
template <class T>
T Add(T a, T b)
{
std::cout << "普通模板函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
template <class T>
static T StaticAdd(T a, T b)
{
std::cout << "静态模板函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
int main()
{
// 1 普通函数
std::function<int(int, int)> addFunc1 = Add<int>;
addFunc1(1, 2);
// 2 普通函数指针
std::function<int(int, int)> addFunc2 = &Add<int>;
addFunc2(3, 4);
// 3 静态函数
std::function<int(int, int)> staticAddFunc1 = StaticAdd<int>;
staticAddFunc1(5, 6);
// 4 静态函数指针
std::function<int(int, int)> staticAddFunc2 = &StaticAdd<int>;
staticAddFunc2(7, 8);
getchar();
return 0;
}
2.2 包装类成员函数和类静态函数
2.2.1 非模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
class A
{
public:
typedef std::shared_ptr<A> ptr;
A()
{
};
virtual~A()
{
};
public:
int A_Add_Public(int a, int b)
{
std::cout << "类公有成员函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
static int A_Add_Static(int a, int b)
{
std::cout << "类静态函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
public:
int m_Value = 20;
};
int main()
{
// 1 类公有成员函数
A m_a;
std::function<int(int, int)> addFunc1 = std::bind(&A::A_Add_Public, &m_a, std::placeholders::_1, std::placeholders::_2);
addFunc1(1, 2);
// 2 类静态函数
std::function<int(int, int)> addFunc2 = &A::A_Add_Static;
addFunc2(1, 2);
getchar();
return 0;
}
2.2.2 模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
class A
{
public:
typedef std::shared_ptr<A> ptr;
A()
{
};
virtual~A()
{
};
public:
template <class T>
T A_Add_Public(T a, T b)
{
std::cout << "类公有模板成员函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
template <class T>
static T A_Add_Static(T a, T b)
{
std::cout << "类静态模板函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
public:
int m_Value = 20;
};
int main()
{
// 1 类公有成员函数
A m_a;
std::function<int(int, int)> addFunc1 = std::bind(&A::A_Add_Public<int>, &m_a, std::placeholders::_1, std::placeholders::_2);
addFunc1(1, 2);
// 2 类静态函数
std::function<int(int, int)> addFunc2 = &A::A_Add_Static<int>;
addFunc2(1, 2);
getchar();
return 0;
}
2.3 包装Lambda表达式
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
int main()
{
// 1 lambda表达式
std::function<int(int, int)> addFunc1 = [](int a, int b) ->int {
std::cout << "lambda表达式被调用,结果为:" << a + b << std::endl;
return a + b;
};
addFunc1(1, 2);
getchar();
return 0;
}
2.4 包装类重载操作符()函数
2.4.1 非模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
class A
{
public:
typedef std::shared_ptr<A> ptr;
A()
{
};
virtual~A()
{
};
public:
int operator()(int a, int b)
{
std::cout << "类重载操作符()函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
public:
int m_Value = 20;
};
int main()
{
// 1 类重载操作符()函数
std::function<int(int, int)> addFunc1 = A();
addFunc1(1, 2);
getchar();
return 0;
}
2.4.2 模板类型
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
template <class T>
class A
{
public:
typedef std::shared_ptr<A> ptr;
A()
{
};
virtual~A()
{
};
public:
T operator()(T a, T b)
{
std::cout << "类重载操作符()模板函数被调用,结果为:" << a + b << std::endl;
return a + b;
}
public:
int m_Value = 20;
};
int main()
{
// 1 类重载操作符()函数
std::function<int(int, int)> addFunc1 = A<int>();
addFunc1(1, 2);
getchar();
return 0;
}
2.5 包装类共有成员变量
代码示例:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
class A
{
public:
typedef std::shared_ptr<A> ptr;
A()
{
};
virtual~A()
{
};
public:
int Add()
{
return m_Value;
}
public:
int m_Value = 20;
};
int main()
{
// 1 类共有成员变量
std::function<int(A&)> A_Value = &A::m_Value;
A m_a;
std::cout << "m_a对象的成员m_Value的值为:" << A_Value(m_a) << std::endl;
getchar();
return 0;
}
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:C++11 – std::function简要介绍以及可包装函数的几种形式总结
原文链接:https://www.stubbornhuang.com/916/
发布于:2020年09月24日 16:07:25
修改于:2023年06月26日 22:15:37
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论
50