【现代C++】functional模板库之function详解

文章目录

  • 1. 参考文档
  • 2. `std::funtion` 简介
  • 3. `std::function` 样例
    • ① 包装普通函数
    • ② 包装普通函数指针
    • ③ 包装类成员函数指针
      • a. 类静态成员函数
      • b. 类对象成员函数
    • ④ 包装函数对象
    • ⑤ 包装lambda表达式对象


1. 参考文档

两个常用的C++参考文档:

  • cplusplus.comhttp://www.cplusplus.com/reference/functional/function/
  • cppreference.comhttps://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 = &sub;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;
} 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部