【现代C++】functional模板库之function详解
文章目录
- 1. 参考文档
- 2. `std::funtion` 简介
- 3. `std::function` 样例
- ① 包装普通函数
- ② 包装普通函数指针
- ③ 包装类成员函数指针
- a. 类静态成员函数
- b. 类对象成员函数
- ④ 包装函数对象
- ⑤ 包装lambda表达式对象
1. 参考文档
两个常用的C++参考文档:
cplusplus.com:http://www.cplusplus.com/reference/functional/function/cppreference.com:https://en.cppreference.com/w/cpp/utility/functional/function
2. std::funtion 简介
std::function 是一个类模板,其声明如下:
// MS C++ 2013
template<class _Fty> class function;
template<class _Fty> class function : public _Get_function_impl<_Fty>::type { ... }// GCC 4.8.2
template<typename _Signature> class function;
template<typename _Res, typename... _ArgTypes> class function<_Res(_ArgTypes...)>: public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>, private _Function_base { ... }// cplusplus.com
template <class T> function; // undefined
template <class Ret, class... Args> class function<Ret(Args...)>;
关于此类模板的说明:
std::function是一个函数包装器模板function wrapper template,原本来自于boost库,对应其中的boost::function函数包装器,C++11将其纳入了标准库之中。std::function能包装任何类型的可调用元素callable element,例如普通函数function和函数对象function object。包装器对象的类型仅仅依赖于其调用特征call signature,而不依赖于可调用元素自身的类型callable element type itself。- 一个
std::function类型的实例对象可以包装这样几种可调用类型callable object:普通函数function、普通函数指针function pointer、类成员函数指针pointer to member或者任意类型的函数对象function object(例如定义了operator()并且拥有函数闭包)。 std::function对象可以被拷贝copied和移动moved,并且可以使用指定的调用特征直接调用可调用类型。- 当
std::function对象没有包装任何实际的可调用元素时,即为空函数empty function,调用该对象将抛出std::bad_function_call异常。
模板参数的说明:
T:通用类型,但实际通用类型模板generic template并没有被定义,只有当T的类型为形如Ret(Args...)的函数类型才能工作。Ret:调用函数返回值的类型。Args:函数参数类型。这是一个能包装任意数量类型的模板参数。对于指向成员函数的指针,第一个类型应为指向成员的类类型的引用a reference to the class type the member pointed is a member。
3. std::function 样例
① 包装普通函数
非模板类型:
#include
#include int sub(int i, int j) { return i - j; } int main() {std::function<int(int, int)> f = sub;std::cout << f(1, 2) << std::endl; //-1return 0;
}
模板类型:
#include
#include template <typename T>
T sub(T i, T j) { return i - j; } int main() {std::function<double(double, double)> f = sub<double>; //传递模板参数std::cout << f(1, 2) << std::endl; return 0;
}
② 包装普通函数指针
非模板类型:
#include
#include int sub(int i, int j) { return i - j; } int main() {std::function<int(int, int)> f = ⊂std::cout << f(1, 2) << std::endl; return 0;
}
模板类型:
#include
#include template <typename T>
T sub(T i, T j) { return i - j; } int main() {std::function<double(double, double)> f = &sub<double>; //传递模板参数std::cout << f(1, 2) << std::endl; return 0;
}
③ 包装类成员函数指针
a. 类静态成员函数
非模板类型:
#include
#include class Ops {
public:static int sub(int i, int j) { return i - j; }
};int main() {std::function<int(int, int)> f = &Ops::sub;std::cout << f(1, 2) << std::endl; return 0;
}
模板类型:
#include
#include class Ops {
public:template <typename T>static T sub(T i, T j) { return i - j; }
};int main() {std::function<double(double, double)> f = &Ops::sub<double>;std::cout << f(1, 2) << std::endl; return 0;
}
b. 类对象成员函数
非模板类型:
#include
#include class Ops {
public:int sub(int i, int j) { return i - j; }
};int main() {Ops m;std::function<int(int, int)> f = std::bind(&Ops::sub, &m, std::placeholders::_1, std::placeholders::_2); //return m.substd::cout << f(1, 2) << std::endl; return 0;
}
模板类型:
#include
#include class Ops {
public:template <typename T>T sub(T i, T j) { return i - j; }
};int main() {Ops m;std::function<double(double, double)> f = std::bind(&Ops::sub<double>, &m, std::placeholders::_1, std::placeholders::_2); //return m.sub std::cout << f(1, 2) << std::endl; return 0;
}
④ 包装函数对象
非模板类型:
#include
#include struct Ops {int operator()(int i, int j) {return i - j;}
};int main() {std::function<int(int, int)> f = Ops();std::cout << f(1, 2) << std::endl; return 0;
}
模板类型:
#include
#include template <typename T>
struct Ops {T operator()(T i, T j) {return i - j;}
};int main() {std::function<double(double, double)> f = Ops<double>();std::cout << f(1, 2) << std::endl; return 0;
}
⑤ 包装lambda表达式对象
#include
#include auto sub = [](int i, int j) { return i - j; };int main() {std::function<int(int, int)> f = sub;std::cout << f(1, 2) << std::endl; return 0;
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
