Day 29 C++ STL- Function Object (Function Object) (Functor)

function object concept

concept

  • A class that overloads the function call operator , its object is often called a function object
  • When a function object uses overloaded (), it behaves like a function call, also called a functor

A function object is an object that behaves like a function. It is a class or structure that overloads the function call operator operator(). When using a function object, it can be called like a function.

Function objects can have state and maintain state between calls, which makes function objects more flexible and powerful than ordinary functions in some cases.

Nature

A function object (functor) is an overloaded 函数调用操作符()class, not a function

function object using

features

  • When a function object is used, it can be called like a normal function , it can have parameters, and it can have a return value
  • Function objects go beyond the concept of ordinary functions, and function objects can have their own state
  • Functors are very flexible and can be passed as parameters .

example

#include <iostream>
#include <algorithm>
#include <vector>

// 函数对象类
class MultiplyBy {
public:
    MultiplyBy(int factor) : factor_(factor) {}

    int operator()(int x) const {
        return x * factor_;
    }

private:
    int factor_;
};

int main() {
    // 创建函数对象实例
    MultiplyBy multiplyByTwo(2);

    // 函数对象调用
    int result = multiplyByTwo(3);  // 结果为 6
    std::cout << "Result: " << result << std::endl;

    // 函数对象作为参数传递给算法
    std::vector<int> nums = {1, 2, 3, 4, 5};
    std::transform(nums.begin(), nums.end(), nums.begin(), MultiplyBy(3));

    // 输出结果:3 6 9 12 15
    for (int num : nums) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

In the above example, we defined a function object class MultiplyBy, which accepts an integer parameter, and multiplies the incoming parameter with the element in the function call operator(). We use the function object instance multiplyByTwo to make a function call, and pass the function object MultiplyBy(3) as a parameter to the std::transform() algorithm to multiply the elements in the container nums.


predicate - return functor of type bool

predicate concept

  • Functors that return bool type are called predicates
  • If operator() takes one argument, it is called a unary predicate
  • If operator() takes two arguments, it is called a binary predicate

unary predicate - a predicate with only one argument to operator()

#include <vector>
#include <algorithm>

//1.一元谓词
struct GreaterFive{
	bool operator()(int val) {
		return val > 5;
	}
};

void test01() {

	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());
	if (it == v.end()) {
		cout << "没找到!" << endl;
	}
	else {
		cout << "找到:" << *it << endl;
	}
}

int main() {
	test01();
	system("pause");
	return 0;
}

Binary predicate - a predicate with only two arguments to operator()

#include <vector>
#include <algorithm>
//二元谓词
class MyCompare
{
public:
	bool operator()(int num1, int num2)
	{
		return num1 > num2;
	}
};

void test01()
{
	vector<int> v;
	v.push_back(10);
	v.push_back(40);
	v.push_back(20);
	v.push_back(30);
	v.push_back(50);

	//默认从小到大
	sort(v.begin(), v.end());
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
	cout << "----------------------------" << endl;

	//使用函数对象改变算法策略,排序从大到小
	sort(v.begin(), v.end(), MyCompare());
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}

First, in the test01() function, we create an integer vector v and add some numeric elements.

We then sort v using the default sorting algorithm std::sort(). Since the default sorting strategy is sorting from small to large, the output is 10 20 30 40 50.

Next, we use the function object MyCompare passed as a parameter to std::sort() to change the sorting strategy. In MyCompare, we overloaded the function call operator operator(), and implemented a custom sorting rule, that is, sorting in descending order. Pay attention MyCompareto bring()

By using the function object MyCompare(), we re-sort the vector v, this time the output result is 50 40 30 20 10, which is contrary to the last sorting result and conforms to the sorting strategy we set from large to small.

Finally, we call the test01() function in the main() function to test the sorting results

Builtin Function Objects

built-in function object concept

Built-in function objects are predefined function objects provided by the C++ standard library. These function objects are usually used in algorithms and containers, and can provide various functions, such as sorting, searching, counting, etc., and they can be used for common arithmetic and logical operations. These built-in function objects are usually implemented through function template classes, and are provided and used with specific names.

Notice

  • The objects generated by these functors are used in exactly the same way as ordinary functions
  • To use the built-in function object, you need to import the header file#include<functional>

Arithmetic Functor - Implementing Four Arithmetic Operations

Among them, negate is a unary operation, and the others are binary operations.

functor prototype
  • template<class T> T plus<T>// addition functor
  • template<class T> T minus<T>//subtraction functor
  • template<class T> T multiplies<T>// multiplication functor
  • template<class T> T divides<T>// division functor
  • template<class T> T modulus<T>//Take the imitation function
  • template<class T> T negate<T>// take inverse functor
example
#include <functional>
//negate
void test01()
{
	negate<int> n;
	cout << n(50) << endl;
}

//plus
void test02()
{
	plus<int> p;
	cout << p(10, 20) << endl;
}

int main() {
	test01();
	test02();
	system("pause");
	return 0;
}

Relational functors - implementing relational comparisons

functor prototype
  • template<class T> bool equal_to<T>//equal
  • template<class T> bool not_equal_to<T>//not equal to
  • template<class T> bool greater<T>//more than the
  • template<class T> bool greater_equal<T>//greater or equal to
  • template<class T> bool less<T>//less than
  • template<class T> bool less_equal<T>// less than or equal to
example
#include <functional>
#include <vector>
#include <algorithm>

class MyCompare
{
public:
	bool operator()(int v1,int v2)
	{
		return v1 > v2;
	}
};
void test01()
{
	vector<int> v;

	v.push_back(10);
	v.push_back(30);
	v.push_back(50);
	v.push_back(40);
	v.push_back(20);

	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;

	//自己实现仿函数
	//sort(v.begin(), v.end(), MyCompare());
	//STL内建仿函数  大于仿函数
	sort(v.begin(), v.end(), greater<int>());

	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}

Logical functors - implement logical operations

function prototype
  • template<class T> bool logical_and<T>// logical AND
  • template<class T> bool logical_or<T>// logical or
  • template<class T> bool logical_not<T>// logical NOT
example
#include <vector>
#include <functional>
#include <algorithm>
void test01()
{
	vector<bool> v;
	v.push_back(true);
	v.push_back(false);
	v.push_back(true);
	v.push_back(false);

	for (vector<bool>::iterator it = v.begin();it!= v.end();it++)
	{
		cout << *it << " ";
	}
	cout << endl;

	//逻辑非  将v容器搬运到v2中,并执行逻辑非运算
	vector<bool> v2;
	v2.resize(v.size());
	transform(v.begin(), v.end(),  v2.begin(), logical_not<bool>());
	for (vector<bool>::iterator it = v2.begin(); it != v2.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}

insert image description here

Guess you like

Origin blog.csdn.net/m0_74921567/article/details/132256996