Function object: lamda expression


The need to sort when and how fast to achieve the sort. C ++ algorithm library provides us with the sort function, which is implemented by the underlying fast row. sort function can pass two parameters, a start address Sort element, the second element is the ordered end address, so that the incoming parameters, default sort ascending row.
When you just need a simple way to sort rows in ascending time, we sort of need to use the third argument, sorted. The following pseudo function to understand and lamda expression through the realization of this sort.

Functor: function objects

Functor, also called pseudo function. As the name suggests, it is not really a function. To a normal class, a heavy load (), is realized in the definition of pseudo function.

struct  classFunc
{
	int operator(/*重载运算符*/)(int a,int b /*形参列表*/)
	{
		return a + b;
	}
};

Function object in the functional header file

Functor is not the function of the object, so we can define a function object, and then uses the callback function object implementations.
In fact, sort () function is to realize the underlying functor, for example, you want to row in descending order, you need to call.

#include<iostream>
#include<algorithm>
#include<vector>
#include<functional>//greater<int>()包含在这个头文件
using namespace std;

int main()
{
	vector<int> num{ 11, 22, 50, 7, 90, 4333, 5 };
	sort(num.begin(), num.end(),greater<int>());//底层采用模板实现,所以应该指明类型
	for (int i : num)
		cout << i<<"  ";
	system("pause");
}

functional header file is a C ++ language library function object to achieve, commonly used function object as follows:

Overload operator Function object
> greater<T>()
< less<T>()
>= greater_equal<T>()
<= less_equal<T>()

Custom function object

Of course, we can define your own function object:

#include<iostream>
using namespace std;

struct  classFunc
{
	int operator()(int a,int b)
	{
		return a + b;
	}
};
int main()
{
	classFunc f;//定义函数对象
	cout << f(20, 40) << endl;
	system("pause");
}

Custom function object implements sort functions sort, sort the items installed by the high price in the end, because the function object class template mygreater not implemented, there is no need to develop parameter type.

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
struct Goods{
	string name;
	double price;
};
struct mygreater{
	bool operator()(const Goods& g1, const Goods& g2)
	{
		return g1.price > g2.price;
	}
};
int main()
{
	vector<Goods> Gd{ { "苹果", 2.1 }, { "相交", 3 }, \
	{ "橙子", 2.2 }, { "菠萝", 1.5 } };
	
	sort(Gd.begin(), Gd.end(), mygreater());
	
	for (Goods& i : Gd)
		cout << i.name << ":" << i.price << endl;
	system("pause");
}

lamda expression

We see that the function object to write somewhat cumbersome, sometimes we may achieve this function object, then once it is no longer used. C ++ 11 provides such a case, an easier implementation lamda expressions.

[capture-list] (parameters) mutable -> return-type {
 statement }
  • [capture-list]: capture list, which always appear at the beginning of the lambda function, the compiler is determined according to the following []
    whether the code is lambda functions, capturing context list can capture the variables used for lambda function.
  • (parameters): list of parameters. Consistent with the ordinary function parameter list, if no parameters are passed, together with the can ()
    is omitted
  • mutable: By default, lambda function is always a const function, mutable can cancel their constant nature. When this modifier, the parameter list can not be omitted (even though the parameter is empty).
  • -> return-type: the type of the return value. Return form type declaration of the function return value is a tracking type, no return value in this section
    may be omitted. Return Value Type clear circumstances, may be omitted, derivation of the type returned by the compiler.
  • {Statement}: the function thereof. In the in vivo function, except that its parameters can be used, but also can be used to capture all of the variables.

Note: in the lambda-defined function, the parameter list and return type is an optional part, while the body and functions to capture list may be empty. Thus the simplest lambda functions as C ++ 11: [] {}; the lambda functions can not do anything.

#include<iostream>
using namespace std;
int main()
{
	int a = 10, b = 20;
	auto Func = [&]()mutable ->int{
		int c = a;
		a = b;
		b = c;
		return a + b;
	};
	cout << a << endl << b << endl << Func() << endl;
	system("pause");
}

As can be seen by the above example, lambda expressions can actually be understood as unknown function, which can not be called directly, if you want to direct calls, can make use of auto assign it to a variable.

note:

  1. Parent scope statement refers to the function block contains lambda
  2. Capture list may be composed of a plurality of captured items on grammar and comma-separated.
    For example:
    [=, & a, & B]: reference passed capture variables a and b, the value of transmission mode to capture all other variables
    [&, a, this]: passed by value capture variables a and this, reference capture other variables
  3. Capture list does not allow variable repeat pass, otherwise it will cause a compiler error. For example: [=, a]: = the value has passed all the way to capture the variables, a repeat capture.
  4. lambda functions outside the scope capture block list must be empty.
  5. In function block lambda scope of local variables only capture parent scope, this scope or capture any non-local variables will lead to non compile error.
  6. Lambda expressions can not be assigned each other, even seemingly the same type.

The same items are ranked in descending price installation, use lamda expression achieved:

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
struct Goods{
	string name;
	double price;
};

int main()
{
	vector<Goods> Gd{ { "苹果", 2.1 }, { "相交", 3 }, \
	{ "橙子", 2.2 }, { "菠萝", 1.5 } };

	sort(Gd.begin(), Gd.end(), [](const Goods& g1, const Goods&g2)\
	{return g1.price > g2.price; });

	for (Goods& i : Gd)
		cout << i.name << ":" << i.price << endl;
	system("pause");
}

lamda expression and function objects

#include<iostream>
using namespace std;

class Rate
{
public:
	Rate(double rate)
		: _rate(rate)
	{}
	double operator()(double money, int year)
	{
		return money * _rate * year;
	}
private:
	double _rate;
};
int main()
{
	// 函数对象
	double rate = 0.49;
	Rate r1(rate);
	r1(10000, 2);
	// lamda表达式
	auto r2 = [=](double monty, int year)->double{return monty*rate*year; };
	r2(10000, 2);
	system("pause");
	return 0;
}

Here Insert Picture Description
In the actual bottom treatment compiler for lambda expressions, is entirely a function of the manner the object of processing, namely: if a lambda expression is defined, the compiler will automatically generate a class, the class in the overloaded operator ( ).

Guess you like

Origin blog.csdn.net/Vickers_xiaowei/article/details/89882093