Lambda expression, callback function, bind(), function()

Lambda expression, callback function, std::bind() std::function()

Lambda expression

Equivalent to an anonymous function, there is no need to write an additional function or function object, avoiding code expansion and function dispersion.

Take the following code as an example to explain, demo.cpp:

config.applyMsgCallback = [](const raft::ApplyMessage& msg) {
        assert(msg.command.getStringView() == "raft example");
    };
config.snapshotCallback = [](const json::Value& snapshot) {
        FATAL("not implemented yet");
    };

grammatical form

[ c a p t u r e ] ( p a r a m s ) o p t − > r e t { b o d y ; } ; [capture](params)opt->ret\{body;\}; [capture](params)opt>ret{ body;};

  • capture: capture list
  • params: parameter list
  • opt: function options
  • ret: return value type
  • body: function body
    auto func = [](int a)->int{return a+1;};
    std::cout<<func(2)<<"\n";  // output 3

omit return type

auto func = [](int a){return a+1;};
auto x2 = [](){ return { 1, 2 }; };  // error: 无法推导出返回值类型这时我们需要显式给出具体的返回值类型。

no parameter list, parameter list omitted

auto func = [](){return 1;};
auto f = []{return 1;}; // 直接省略空的参数列表

capture list

  • [ ] does not capture any variables
  • [&] captures all variables in the outer scope and uses them as references in the function body (capture by reference)
  • [=] captures all variables in the outer scope and uses them as copies in the function body (capture by value)
  • [=, &foo] captures all variables in the outer scope by value, and the foo variable by reference
  • [bar] Capture the bar variable by value, while not capturing other variables
  • [this] captures the this pointer in the current class, so that the lambda expression has the same access rights as the member functions of the current class. If & or = is already used, this option is added by default. The purpose of capturing this is to use the member functions and member variables of the current class in lamda
// example

class LAM{
public:
    int index = 0;
    void func(int x,int y){
        // auto x1 = []{return index;}; // error 没有捕获外部变量
        auto x2 = [=]{return index + x + y;}; // 捕获所有外部变量
        auto x3 = [&]{return index + x + y;};
        auto x4 = [this]{return index;}; // cathc this pointer
        // auto x5 = [this]{return index+ x+ y;}; // error
        auto x6 = [this,x,y]{return index+x+y;};
        auto x7 = [this]{return index++;}; //修改成员变量
    }
};
int a = 0, b = 1;
auto f1 = []{ return a; };               // error,没有捕获外部变量
auto f2 = [&]{ return a++; };            // OK,捕获所有外部变量,并对a执行自加运算
auto f3 = [=]{ return a; };              // OK,捕获所有外部变量,并返回a
auto f4 = [=]{ return a++; };            // error,a是以复制方式捕获的,无法修改
auto f5 = [a]{ return a + b; };          // error,没有捕获变量b
auto f6 = [a, &b]{ return a + (b++); };  // OK,捕获a和b的引用,并对b做自加运算
auto f7 = [=, &b]{ return a + (b++); };  // OK,捕获所有外部变量和b的引用,并对b做自加运算

delayed call

int a = 0;
auto f = [=]{ return a; };      // 按值捕获外部变量
a += 1;                         // a被修改了
std::cout << f() << std::endl;  // 输出?

output a = 0; because it is a value capture

Use mutable to modify the value of an external variable captured by value

int a = 0;
auto f1 = [=]{ return a++; };             // error,修改按值捕获的外部变量
auto f2 = [=]() mutable { return a++; };  // OK,mutable

Callback

function pointer

Simple explanation - understanding c/c++ function pointers - Zhihu (zhihu.com)

int foo()
{
    return 5;
}

The function type is int (*somefunction)()

If it is "there are two *integer* parameters and the return value is Boolean ", we can express it like thisbool (*someotherfunction)(int, int)

Like variables, functions have fixed addresses in memory. The essence of a function is also a fixed space in memory.

int (*const funcPtr)();
// 另外,对于 
const int(*funcPtr);
// 意思是这个指针指向的函数的返回值是常量
int foo()
{
    
    
    return 5;
}
 
int goo()
{
    
    
    return 6;
}
int (*funcPtr)() = foo;
funcPtr = goo;
  //但是千万不要写成funcPtr = goo();这是把goo的返回值赋值给了funcPtr

Calling a function through a function pointer

int foo(int x)
{
    
    
    return x;
}
 
int main()
{
    
    
    int (*funcPtr)(int) = foo; 
    (*funcPtr)(5); // 通过funcPtr调用foo(5)
    funcPtr(5) // 也可以这么使用,在一些古老的编译器上可能不行
    return 0;
}

Pass function pointer as parameter

#include <iostream>
int add(int a, int b){
    
    
    return a+b;
}
int sub(int a, int b){
    
    
    return a-b;
}
void func(int e, int d, int(*f)(int a, int b)){
    
     // 这里才是我想说的,
// 传入了一个int型,双参数,返回值为int的函数
    std::cout<<f(e,d)<<std::endl;
}
int main()
{
    
    
    func(2,3,add);
    func(2,3,sub);

    return 0;
}

callback

A callback function is a function that is called through a function pointer. The callback function, as the name implies, is a function defined by the user himself, the user implements the program content of this function, and then passes this function as a parameter into the function of others (or the system), and the function of the other person (or system) runs function to be called. The function is implemented by you, but it is called by other people's (or system) functions by passing parameters at runtime, which is the so-called callback function. To put it simply, it is to call back the function you implemented during the running of other people's functions.

Callback function of C++ learning_c++ callback function_HAH-M's Blog-CSDN Blog

std::function()

[C++] Detailed usage of std::function and std::bind of C++11_c++ bind object member function to ordinary function_Yngz_Miao's Blog-CSDN Blog

std::function is a callable object wrapper and a class template that can hold all callable objects except class member function pointers. It can handle functions, function objects, and function pointers in a unified way, and allows saving and delay their execution .

The role of std::function can be attributed to:

std::function encapsulates various callable entities in C++ (ordinary functions, Lambda expressions, function pointers, and other function objects, etc.), forming a new callable std::function object to simplify calls; std
: The :function object is a type-safe wrapper for existing callable entities in C++ (for example, callable entities such as function pointers are type-unsafe)

so:

 struct RequestVoteArgs;
    struct RequestVoteReply;
    struct AppendEntriesArgs;
    struct AppendEntriesReply;
    struct ApplyMessage;

    typedef std::function<void( const RequestVoteReply&)> RequestVoteDoneCallback;
    typedef std::function<void( const AppendEntriesReply&)> AppendEntriesDoneCallback;
    typedef std::function<void( const RequestVoteArgs&,
                                const RequestVoteDoneCallback&)> DoRequestVoteCallback;
    typedef std::function<void( const AppendEntriesArgs& args,
                                const AppendEntriesDoneCallback& done)> DoAppendEntriesCallback; 
    typedef std::function<void( int,
                                const RequestVoteArgs&,
                                const RequestVoteReply&)> RequestVoteReplyCallback;
    typedef std::function<void( int,
                                const AppendEntriesArgs&,
                                const AppendEntriesReply&)> AppendEntriesReplyCallback;
    typedef std::function<void( const ApplyMessage&)> ApplyMsgCallback;
    typedef std::function<void( const json::Value&)> SnapshotCallback;

It is equivalent to a template class that defines some function pointers, that is, a callback function

std::bind()

std::bind can be seen as a generic function adapter that takes a callable object and generates a new callable object that adapts the argument list of the original object.

std::bind binds the callable object and its parameters together, and the bound result can be saved using std::function. std::bind mainly has the following two functions:

Bind the callable object and its parameters into a functor;
only bind some parameters to reduce the parameters passed in by the callable object.

The general form of calling bind:

auto newCallable = bind(callable, arg_list);

The meaning of this form is: when called newCallable, it will be called callableand passed to itsarg_list parameters .

For a specific example, pay attention to the placeholders used in parameter binding, std::placeholders::_1

int main(int argc, char * argv[]) {
    
    
    //f1的类型为 function<void(int, int, int)>
    auto f1 = std::bind(fun_1, 1, 2, 3); 					//表示绑定函数 fun 的第一,二,三个参数值为: 1 2 3
    f1(); 													//print: x=1,y=2,z=3
auto f2 = std::bind(fun_1, std::placeholders::_1, std::placeholders::_2, 3);
//表示绑定函数 fun 的第三个参数为 3,而fun 的第一,二个参数分别由调用 f2 的第一,二个参数指定
f2(1, 2);												//print: x=1,y=2,z=3
 
auto f3 = std::bind(fun_1, std::placeholders::_2, std::placeholders::_1, 3);
//表示绑定函数 fun 的第三个参数为 3,而fun 的第一,二个参数分别由调用 f3 的第二,一个参数指定
//注意: f2  和  f3 的区别。
f3(1, 2);												//print: x=2,y=1,z=3

int m = 2;
int n = 3;
auto f4 = std::bind(fun_2, std::placeholders::_1, n); //表示绑定fun_2的第一个参数为n, fun_2的第二个参数由调用f4的第一个参数(_1)指定。
f4(m); 													//print: a=3,b=4
std::cout << "m = " << m << std::endl;					//m=3  说明:bind对于不事先绑定的参数,通过std::placeholders传递的参数是通过引用传递的,如m
std::cout << "n = " << n << std::endl;					//n=3  说明:bind对于预先绑定的函数参数是通过值传递的,如n

A a;
//f5的类型为 function<void(int, int)>
auto f5 = std::bind(&A::fun_3, &a, std::placeholders::_1, std::placeholders::_2); //使用auto关键字
f5(10, 20);												//调用a.fun_3(10,20),print: k=10,m=20

std::function<void(int,int)> fc = std::bind(&A::fun_3, a,std::placeholders::_1,std::placeholders::_2);
fc(10, 20);   											//调用a.fun_3(10,20) print: k=10,m=20 

return 0; 

The following code is to bind the parameter list to the callback function, then call setRequestVoteReplyCallback, pass the parameters, and then execute OnRequestVoteReply.

for(auto peer : rawPeers){
        peer->setRequestVoteReplyCallback(std::bind(&Node::OnRequestVoteReply,this,_1,_2,_3));
        peer->setAppendEntriesReplyCallback(std::bind(&Node::OnAppendEntriesReply,this,_1,_2,_3));
    }
    raftService.setDoRequestVoteCallback(std::bind(&Node::RequestVote,this,_1,_2));
    raftService.setDoAppendEntriesCallback(std::bind(&Node::AppendEntries,this,_1,_2));

Guess you like

Origin blog.csdn.net/qq_47865838/article/details/129914900