C++ lambda expressions

C++11 and later lambda expressions are a powerful tool for representing a callable unit of code. Can be understood as an unnamed inline function. A lambda expression has the form:

[capture list] (parameter list) -> return type { function body }

We can ignore parameter lists and return types, but must always include capture lists and function bodies.

auto f = [] { return 42; };
cout << f() << endl; // print 42

Lambda expressions are often used with for_each and iterators. As follows, each value in the vector needs to be squared:

#include <iostream>
using namespace std;

int main(int argc, const char * argv[]) {
    vector<int> test = {3,2,5}; 
    for(auto v: test) cout << v << " ";
    cout << endl;
    for_each(test.begin(), test.end(), [] (int& a) { a *= a; });
    for(auto v: test) cout << v << " ";
    cout << endl;
    return 0;
}

Here is the output:

write picture description here

Of course, in addition to this method, you can also use function pointers to solve this problem:

#include <iostream>
using namespace std;

typedef int (*pf)(int);
template <class T>
void square(vector<T>& vec, pf func) {
    for (auto &v: vec) v *= v; // need to use reference
}


int main(int argc, const char * argv[]) {
    vector<int> test = {3,2,5};

    for(auto v: test) cout << v << " ";
    cout << endl;

    square(test, squareTest);
    //for_each(test.begin(), test.end(), [](int& a){ a *= a; });

    for(auto v: test) cout << v << " ";
    cout << endl;
    return 0;
}

The end result is the same.
This can achieve the same effect using map directly in Python:

def squareTest(a):
    return a**2

test = [3,2,5]
print(test)
print(map(squareTest, test))
# print(map(lambda a : a**2 , test)) # can use lambda as well

The first parameter in the map represents the function that needs to be implemented, while the second parameter represents the object that the function implements. For lambda, it is similar to C++, but the syntax is different.

The following describes the capture list in lambda. The capture list can be passed by value, that is, a copy is passed in, or passed by reference, that is, a reference is passed. The operation on the reference will directly affect the referenced object. value of .
Here is an example to illustrate:

int main(int argc, const char * argv[]) {
    size_t v1 = 42;
    auto f = [v1] { return v1; };
    v1 = 2;
    auto j = f(); 
    cout << j << endl; // j = 42

    size_t v2 = 42;
    auto f1 = [&v2] { return v2; };
    v2 = 2;
    auto k = f1();
    cout << k << endl; // k = 2
    return 0;
}

The first is the incoming value, and the last output is the value of the previous copy of v1. The change of v1 will not affect the value of the last j, so the value of the last j is still 42. As for the reference passed in in the second example, this reference points to the referenced object, that is, v2, so they are happily bound together, and if v2 is changed later, the reference will follow, that is, at the end The value of k also becomes 2.

In fact, you can also change the incoming captured value. For value transfer, you need to add a keyword mutable. For reference passing, whether or not it can be changed depends on whether the incoming value is of const type. If it is, it cannot; if not, it can. Then look at the following example:

int main(int argc, const char * argv[]) {
    size_t v1 = 42;
    auto f = [v1] () mutable { return ++v1; };
    v1 = 2;
    auto j = f();
    cout << j << endl; // j = 43
    cout << v1 << endl; // v1 = 2

    size_t v2 = 42;
    auto f1 = [&v2] { return ++v2; };
    v2 = 2;
    auto k = f1();
    cout << k << endl; // k = 3
    cout << v2 << endl;// v2 = 3

    return 0;
}

Here, the value of the calling lambda expression and the captured value are output respectively. For pass-by-value, the value of the copy of v1 is changed, so j is equal to 43, while v1 is still 42; for pass-by-reference, due to binding reasons, the value of the referenced variable will also change, so Finally, the values ​​of k and v2 both become 3.

write picture description here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325721389&siteId=291194637