Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the code `[&]()` mean in c++? [duplicate]

Tags:

c++

idioms

I was poking around a Visual Studio template for a DirectX App. I came across the line m_time.Tick([&]() { ... });, and I cannot figure out what the [&]() part means. I'm not even sure if this is a stupid question because I'm pretty inexperienced in c++.

I know a [] is used for a lambda expression, but I'm not sure that makes sense. Maybe some weird delegate idiom? I don't even know. If you can point me in the direction of a list of other obscure idioms I might come across while attempting to learn c++ I would appreciate it very much.

like image 441
postitman Avatar asked Jul 18 '15 18:07

postitman


People also ask

What does [] mean in coding?

What Does Bracket Mean? Brackets, or braces, are a syntactic construct in many programming languages. They take the forms of "[]", "()", "{}" or "<>." They are typically used to denote programming language constructs such as blocks, function calls or array subscripts. Brackets are also known as braces.

What are the 4 types of code?

While the names of the coding paradigms sometimes vary, most experts agree on four primary types of code: imperative, functional, logical, and object-oriented.

What are () in programming?

Basically, [] are used for lists, and () is the parentheses , which comes round when you're taking an argument as a function or when calling a function.

What is code example?

A code sample is a complete web page or application, with references to all required source files in its description.


4 Answers

This is an example of a lambda function.

C++ is full of obscure corners, but as odd syntax goes, lambda functions are well worth learning. The basic syntax to declare a lambda function is []() { }. This is an expression that results in an object of an implementation-defined type that can be called as if it were a function (because, somewhere in the compiler's implementation of the lambda expression syntax, it is a function).

The first advantage that this gives is that the function can be declared inline with the rest of the code, instead of having to be declared apart (which is often inconvenient for very short or specific-use functions).

The most powerful part of lambda expressions, though, is their ability to capture variables from the surrounding context: That's what the & does in your sample code. A lambda declared with [&] captures all variables (and the implicit this pointer if used inside a method) by reference. (There's also [=] to capture by value, and even an extended syntax to capture only specific variables in specific ways.)

In short, this code:

m_time.Tick([&]() { ... });

calls the Tick method on the m_time object, and passes it a lambda function that captures the surrounding context by reference. Presumably, the Tick method then calls this lambda function during its execution. Within the ..., the variables available in the scope in which the lambda was declared can be then be used -- and this capturing ability is the most powerful and convenient feature of lambdas.

like image 167
Cameron Avatar answered Nov 03 '22 09:11

Cameron


From the C++ Primer

[&] Implicit by reference capture list. Entities from the enclosing function used in the lambda body are used by reference

So practically, think of the [&]() {...} expression as a statement expressing that you want the references to all variables declared in the encompassing scope to be available in the lambda expression. For example...

#include <iostream>

int main(int argc, char** argv) {
    int x = 0;
    int y = 1;

    auto f1 = [&] () { std::cout << x << std::endl; }

    auto f2 = [&x] () { std::cout << x << std::endl; }

    auto f3 = [x] () { std::cout << x << std::endl; }

    ++x;

    f1();
    f2();
    f3();
}
  • f1 will print 1
  • f2 will print 1
  • f3 will print 0

The difference betwee f1 and f2 being that f1 captures the reference of both x and y, while f2 captures the reference to only x. On the other hand f3 captures the value of x (in this case 0) at the time of definition. Since both, f1 and f2 capture the reference to x they will both print 1 when called after x is incremented. However, since f3 captured the value of x at the time of definition, f3 will print 0.

like image 35
Daniel Robertson Avatar answered Nov 03 '22 11:11

Daniel Robertson


It's a lambda expression. It's a pretty typical expression of one. The part in brackets is the lambda's capture clause, and signifies how it interacts with local variables in the enclosing scope. The parentheses would contain the parameter list, just like a function, and then in brackets are the function definition.

Here's a good write up that's not too esoteric. http://www.drdobbs.com/cpp/lambdas-in-c11/240168241

like image 38
mock_blatt Avatar answered Nov 03 '22 10:11

mock_blatt


A lambda expression defines an anonymous function that can capture things from the scope of its definition. In particular, [&] means that it captures all automatic variables by reference and () means that it takes no arguments. What follows in `{...} is the function body. See http://en.cppreference.com/w/cpp/language/lambda for more information on lambdas.

Presumably, Tick expects its parameter to be a callable object; a lambda serves this purpose and is easy to define. An object that defines a call operator would probably work in that context as well. So might a function pointer.

like image 43
user3553031 Avatar answered Nov 03 '22 11:11

user3553031