1

Can someone explain what is going on in the below code snippet line by line

auto enq_func = [](std::queue<reg_t>* q, uint64_t x) { q->push(x); };
std::queue<reg_t> fromhost_queue;
std::function<void(reg_t)> fromhost_callback =
  std::bind(enq_func, &fromhost_queue, std::placeholders::_1);

I think I get the gist of it, that fromhost_queue is a std::queue of each element of type reg_t which was typedef in the beginning of the code as uint64_t and its enqueue functionality is defined using the above three lines something like that.

I have trouble understanding line 1 as I haven't come across this type of function declaration like =[](...){...}; is this some sort of shorthand or something

Also, in the bind() part in line 3, the first argument is a function(here named as enq_func) that bind will be applied on the second argument mostly used to pass a reference of a queue the enq_func will be applied but the last is an argument which will we enqueued but I don't see the enq_func having any arguement

can someone clarify this?

tadman
  • 208,517
  • 23
  • 234
  • 262
  • could to maybe shed a light on what type of declaring is this in line 1 ``` =(...){...}; ``` as I have only come across function defination as ```c++ (){ ...body; } ``` – Shubham Roy Sep 28 '22 at 03:20
  • C++ is complicated enough without this sort of thing going on. It looks like a lot of work to [curry an argument](https://en.wikipedia.org/wiki/Currying), perhaps an artifact of the author's inclination towards Ruby-style `extend` to mix in methods to an existing class. – tadman Sep 28 '22 at 03:20
  • [What is a lambda expression in C++11?](https://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11) – Jesper Juhl Sep 28 '22 at 03:28

1 Answers1

1

This is a slightly overly-complex way to create a function-like callable object that pushes its argument into fromhost_queue. That is, fromhost_callback(123) will end up calling fromhost_queue.push(123).

auto enq_func = [](std::queue<reg_t>* q, uint64_t x) { q->push(x); };

This is a lambda expression that creates a callable object that pushes its second parameter into the queue pointed to by the first parameter. That is, enq_func(&fromhost_queue, 123) will call fromhost_queue.push(123).

std::function<void(reg_t)> fromhost_callback =
  std::bind(enq_func, &fromhost_queue, std::placeholders::_1);

This creates a new callable object that wraps enq_func and automatically supplies its first argument, then stores that in a type-erased std::function container. So fromhost_callback(123) will automatically call enq_func(&fromhost_queue, 123).


There's no reason to do this in two steps though, a single lambda will do fine. Assuming there's a good reason to use std::function then this will do the same thing:

std::queue<reg_t> fromhost_queue;
std::function<void(reg_t)> fromhost_callback =
    [&fromhost_queue](uint64_t x) { fromhost_queue.push(x); }
Miles Budnek
  • 28,216
  • 2
  • 35
  • 52