What does the [&] operator mean before a function?

Asked

Viewed 191 times

9

I’m trying to read the code of a function that’s defined like this:

auto loop = [&](int ntensor, char** data, const int64_t* strides, int64_t n) {
...
  };

What does the [&] before function?

  • This resembles the lambda notation of C++, as can be seen from the code snippet in this question: https://answall.com/q/325704/64969

1 answer

9


This isn’t really a function. Technically it is, but it’s an anonymous function, you seem to know about it, most won’t even see it as a function.

It means that all variables captured by this possible enclosure will be captured as references. This means that their values will not be copied to your function lambda, but only a reference to them will exist within the function and obviously these variables will need to survive at least as long as their lambda exist.

This sets a standard for all captured variables unless one is specified differently.

This is necessary because in catches we do not always want the value in the same way that they were declared.

Note that I am not talking about the parameters, I am talking about possible variables used within your function that were not declared within it (parameters are local to it), and obviously were declared in the function where this lambda was written or in previous scope, but they must be in the scope. I can’t tell if there is any because her body was omitted (and ideally the whole context would show better). Something like this:

void Teste() {
    int i = 1;
    auto loop = [&](int ntensor, char** data, const int64_t* strides, int64_t n) {
        ...
        //faz algo com i aqui e este será uma referência para o i declarado antes
        ...
    };
    //faz algo com loop aqui, possivelmente passar como argumento para outra função
}

There will already be a copy of the value of i and no reference to her:

void Teste() {
    int i = 1;
    auto loop = [=](int ntensor, char** data, const int64_t* strides, int64_t n) {
        ...
        //faz algo com i aqui (neste exemplo eu sei que é 1, poderia ser outro valor)
        ...
    };
    //faz algo com loop aqui, possivelmente passar como argumento para outra função
}

If I didn’t have that i (for example) inside would not be a cloister and so there would be no capture of variables and would not make a difference as the catch was declared.

If no variable is captured by not using any declared outside the scope of lambda then it changes nothing.

A functional example:

#include <iostream>
using namespace std;

int main() {
    int i = 1;
    auto loop = [=]() { cout << i; }; //não pode fazer o incremento aqui
    loop();
    auto loop2 = [&]() { cout << i++; };
    loop2();
    cout << i;
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

In C++ it is possible to say how each variable is captured, but the most common is to use the pattern or all by reference. But you will always have to take care of the life time of the variable, and this is one of the most complicated things if not by value, which makes, in some cases, miss a Garbage Collector.

Documentation.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.