C++ Primer 5th笔记(chap 14 重载运算和类型转换)lambda函数对象

1. 定义

lambda是函数对象:编写一个lambda后,编译器会将该表达式转换成一个未命名类的未命名对象,类中含有一个重载的函数调用运算符。

eg.

stable_sort(words.begin(),words.end(),[](const string &a,const string &b)
{
    
    return a.size() < b.size();});

//等价于下面的类:
class ShorterString{
    
    
public:
	bool operator()(const string &a,const string &b)
	{
    
    return a.size() < b.size();}
};
stable_sort(words.begin(),words.end(),ShorterString());

测试代码:

std::vector<string> words = {
    
     "a31", "b1" };
stable_sort(words.begin(), words.end(), [](const string& a, const string& b)
    {
    
    return a.size() < b.size(); });    
for_each(words.begin(), words.end(), [](const string& s)
    {
    
    std::cout << s << endl; });
    
std::vector<string> words2 = {
    
     "a31", "b1" };
stable_sort(words2.begin(), words2.end(), ShorterString());
for_each(words2.begin(), words2.end(), [](const string& s)
    {
    
    std::cout << s << endl; });

输出结果为

b1
a31
b1
a31

2. 表示 lambda 及相应捕获行为的类

lambda产生的类必须为每个值捕获的变量建立对应的数据成员,同时创建构造函数。

eg.

auto wc = find_if(words.begin(),words.end(),[sz](const string &a)
	{
    
    return a.size() > = sz;})

//该 lambda 表达式产生的类将形如:
class SizeComp
{
    
    
	SizeComp(size_t n):sz(n) {
    
     }
	bool operator()(const string &s)const {
    
    return s.size() >= sz;}
private:
	size_t sz;
}; 

测试代码:

void lambda_functionObject_test2(vector<string>::size_type sz)    {
    
     
	 std::vector<string> words = {
    
     "a31", "b1" };
	 auto wc = find_if(words.begin(), words.end(), [sz](const string& a)
	            {
    
    return a.size() >= sz; });
	std::cout << *wc << endl;
	 
	auto wc2 = find_if(words.begin(), words.end(), SizeComp(sz));
	std::cout << *wc2 << endl;
}
lambda_functionObject_test2(3);

输出结果:

a31
a31

3. 特性

  • lambda默认不能改变它捕获的变量。在默认情况下,由lambda产生的类中的函数调用运算符是一个const成员函数。如果lambda被声明为可变的,则调用运算符就不再是const函数了。
  • 通过引用捕获变量时,由程序负责确保lambda执行时该引用所绑定的对象确实存在。因此编译器可以直接使用该引用而无须在lambda产生的类中将其存储为数据成员。
  • .通过值捕获的变量被拷贝到lambda中,此时lambda产生的类必须为每个值捕获的变量建立对应的数据成员,并创建构造函数,用捕获变量的值来初始化数据成员。
  • .lambda产生的类不包含默认构造函数、赋值运算符和默认析构函数,它是否包含默认拷贝/移动构造函数则通常要视捕获的变量类型而定。

【引用】

[1] 代码functionObject.h

猜你喜欢

转载自blog.csdn.net/thefist11cc/article/details/114162719