东阳的学习笔记
所谓仿函数,是一个定义了 operator()的对象。
仿函数的三大妙处
- 仿函数比一般函数更灵巧,因为它可以拥有状态
- 每个仿函数都有其类别。因此你可以将仿函数作为 template 参数来传递,从而指定某种行为模式。此外还有一个好处:
容器类别也会因为仿函数的不同而不同
仿函数的执行速度比函数指针更快
一个拥有内部状态的仿函数例子
如果要保存状态,则需以reference
传递参数, 或者使用 for_each 的返回值(没错,for_each返回操作)
.
/*
* genera2.cpp
*
* Created on: 2021年1月14日
* Author: san
*/
#include <iostream>
#include <list>
#include <algorithm>
#include "print.hpp"
using namespace std;
class IntSequence {
private:
int value;
public:
// constructor
IntSequence(int initalvalue)
:value(initalvalue)
{
}
// function call
int operator() ()
{
return value++;
}
};
int main()
{
list<int> coll;
IntSequence seq(1);
/* insert values from 1 - 4
* - pass function object by reference
* so that it will continue with five
*/
generate_n<back_insert_iterator<list<int> >,
int, IntSequence &>(back_inserter(coll), // start
4, // number of elements
seq); // generates values
PRINT_ELEMENTS(coll);
// insert value from 42 - 45
generate_n(back_inserter(coll),
3,
IntSequence(42));
// print coll
PRINT_ELEMENTS(coll, "append 42-45: ");
// continue insert with sep
generate_n(back_inserter(coll),
5,
seq);
// print coll
PRINT_ELEMENTS(coll, "add continue: ");
}
配接器
所谓的“函数配接器”是指可以把仿函数和另一个仿函数(或某个值,或某个一般函数)结合起来的仿函数。函数配接器也定义在头文件<functional>
中。
占位符 std::placeholder
C++11的新特性:占位符std::placeholders,其定义如下:
namespace placeholders {
extern /* unspecified */ _1;
extern /* unspecified */ _2;
extern /* unspecified */ _3;
// ...
}
其中 _1 表示回调函数中的第一个参数,_2表示第二个参数…以此类推
C++11中,对C++98标准中函数适配器bind1st/bind2nd进行了泛化和增强,可以传递任何数量的参数
int Add(int num1, int num2)
{
return (num1 + num2);
}
Add(1,2);
//等价于一个具有无参operator()的bind函数对象调用
std::bind(&Add,1,2)();
int Sub(int num1,int num2)
{
return (num1 - num2);
}
std::bind(&Sub,std::placeholders::_1,std::placeholders::_2)(2,1);
//等价于
Sub(2,1);
std::bind(&Sub,std::placeholders::_2,std::placeholders::_1)(2,1);
//等价于
Sub(1,2);
组合型仿函数(也称组合型函数配接器)
使用仿函数,将两个另外的组合,没啥特殊的,下面是一个嵌套的例子:
/*
* compose11.hpp
*
* Created on: 2021年1月9日
* Author: san
*/
#ifndef FO_COMPOSE11_HPP_
#define FO_COMPOSE11_HPP_
#include <functional>
/*
* 一元组合函数配接器
*/
template <class OP1, class OP2>
class compose_f_gx_t
: public std::unary_function<typename OP2::argument_type, // Be careful, OP2 is the first
typename OP1::result_type>
{
private:
OP1 op1; // preocess: op1(op2(x));
OP2 op2;
public:
// constructor
compose_f_gx_t(const OP1 &o1, const OP2 &o2)
: op1(o1), op2(o2) {
}
// function call
typename OP1::result_type
operator() (const typename OP2::argument_type &x)
{
return op1(op2(x));
}
};
/*
* convenience functions for the compose_f_ gx adapter
*/
template <class OP1, class OP2>
inline compose_f_gx_t<OP1, OP2>
compose_f_gx (const OP1 &o1, const OP2 &o2) {
return compose_f_gx<OP1, OP2>(o1, o2);
}
#endif /* FO_COMPOSE11_HPP_ */