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.
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.
While the names of the coding paradigms sometimes vary, most experts agree on four primary types of code: imperative, functional, logical, and object-oriented.
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.
A code sample is a complete web page or application, with references to all required source files in its description.
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.
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 1f2
will print 1f3
will print 0The 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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With