Everything you (n)ever wanted to know about C++'s Lambdas iCSC 2020 Nis Meinert Rostock University
Introduction
2 / 57 3 1 Everything you (n)ever wanted to know about C++’s Lambdas – Introduction 2 Nis Meinert – Rostock University 3 8 4 7 6 5 1 4 2 What is a Lambda Expression in C++ ? cube is a lambda … int main() { auto cube = []( int x) { return x * x * x; }; return cube(3); } godbolt.org/z/zBE2_n is_even is a lambda … #include <algorithm> #include <vector> int main() { std::vector< int > xs{1, 2, 3, 4, 5, 6, 7}; auto is_even = []( int x) { return x % 2 == 0; }; return std::count_if(xs.begin(), xs.end(), is_even); } godbolt.org/z/kWx7qu
Syntax
3 / 57 …is equivalent to Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University 8 7 6 5 4 3 The simplest (and most boring) lambda 1 2 2 4 1 3 …no capturing, takes no parameters and returns nothing A slightly more “useful” lambda 1 C++ 's Lambda Expression auto x = []{}; int main() { int main() { auto x = [] { return 5; }; struct { return x(); auto operator ()() const { } return 5; } godbolt.org/z/DrnSSE } x; return x(); } godbolt.org/z/R8qx3Q
Q: What is the output of the program? 1 2 3 4 5 6 7 Nis Meinert – Rostock University Everything you (n)ever wanted to know about C++’s Lambdas – Syntax 4 / 57 #!/usr/bin/env python3 if __name__ == '__main__': f = {k: lambda x: x + k for k in range (3)} for k in range (3): print (f[k](2), end='')
4 / 57 1 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University Why? implicit capture by reference 7 6 5 4 3 2 A: 444 #!/usr/bin/env python3 if __name__ == '__main__': f = {k: lambda x: x + k for k in range (3)} for k in range (3): print (f[k](2), end='')
Fix 7 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University 11 10 9 8 1 5 / 57 6 5 4 3 2 #!/usr/bin/env python3 from functools import partial if __name__ == '__main__': f = {k: partial( lambda x, k: x + k, k=k) for k in range (3)} # f = {k: lambda x, k=k: x + k for k in range(3)} # ... would change API for k in range (3): print (f[k](2), end='') Now prints: 234
Q: What is the output of the program? 8 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University 15 14 13 12 11 10 1 9 6 / 57 7 3 6 2 5 4 #include <functional> #include <iostream> #include <map> int main() { std::unordered_map< int , std::function< int ( int )>> f; for ( int k = 0; k < 3; k++) { f.emplace(k, []( int x) { return x + k; }); } for ( int i = 0; i < 3; i++) { std::cout << f[i](2); } } godbolt.org/z/QssJXN
Q: What is the output of the program? 9 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University error: “k” is not captured 15 14 13 12 11 10 1 6 / 57 8 3 7 6 5 2 4 #include <functional> #include <iostream> #include <map> int main() { std::unordered_map< int , std::function< int ( int )>> f; for ( int k = 0; k < 3; k++) { f.emplace(k, []( int x) { return x + k; }); } for ( int i = 0; i < 3; i++) { std::cout << f[i](2); } } godbolt.org/z/QssJXN
Q: What is the output of the program? 8 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University 15 14 13 12 11 10 1 9 7 / 57 7 3 6 2 5 4 #include <functional> #include <iostream> #include <map> int main() { std::unordered_map< int , std::function< int ( int )>> f; for ( int k = 0; k < 3; k++) { f.emplace(k, [k]( int x) { return x + k; }); } for ( int i = 0; i < 3; i++) { std::cout << f[i](2); } } godbolt.org/z/qHFY32
A: 234 8 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University 15 14 13 12 11 10 1 9 7 / 57 7 3 6 2 5 4 #include <functional> #include <iostream> #include <map> int main() { std::unordered_map< int , std::function< int ( int )>> f; for ( int k = 0; k < 3; k++) { f.emplace(k, [k]( int x) { return x + k; }); } for ( int i = 0; i < 3; i++) { std::cout << f[i](2); } } godbolt.org/z/qHFY32
Q: What is the output of the program? 8 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University 16 15 14 13 12 11 1 9 10 7 5 2 3 4 8 / 57 6 #include <functional> #include <iostream> #include <map> int main() { std::unordered_map< int , std::function< int ( int )>> f; int k = 0; for (; k < 3; k++) { f.emplace(k, [&k]( int x) { return x + k; }); } for ( int i = 0; i < 3; i++) { std::cout << f[i](2); } } godbolt.org/z/-FTWqI
8 / 57 8 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University 16 15 14 13 12 11 1 9 10 7 5 2 3 6 4 A: 555 (not 444 ) #include <functional> #include <iostream> #include <map> int main() { std::unordered_map< int , std::function< int ( int )>> f; int k = 0; for (; k < 3; k++) { f.emplace(k, [&k]( int x) { return x + k; }); } for ( int i = 0; i < 3; i++) { std::cout << f[i](2); } } godbolt.org/z/-FTWqI
Nis Meinert – Rostock University Capturing rules Everything you (n)ever wanted to know about C++’s Lambdas – Syntax 9 / 57 C++ 's Lambda Expression → [x] : captures x by value → [&x] : captures x by reference → [=] : captures all variables (used in the lambda) by value → [&] : captures all variables (used in the lambda) by reference → [=, &x] : captures variables like with [=] , but x by reference → [&, x] : captures variables like with [&] , but x by value
Capturing by value 12 6 1 7 8 9 10 11 13 4 14 15 16 17 18 19 Nis Meinert – Rostock University Everything you (n)ever wanted to know about C++’s Lambdas – Syntax 5 10 / 57 3 …or equivalently 5 4 7 3 2 2 1 6 int main() { class X { int i = 1; private : auto z = [i]( int y) { int i; return i + y; }(3); public : return z; X( int i): i(i) {} } int operator ()( int y) const { godbolt.org/z/bHveG8 return i + y; } }; // potentially lots of lines of code int main() { int i = 1; auto z = X{i}(3); return z; } godbolt.org/z/8tiwby
Capturing by reference 12 6 1 7 8 9 10 11 13 4 14 15 16 17 18 19 Nis Meinert – Rostock University Everything you (n)ever wanted to know about C++’s Lambdas – Syntax 5 11 / 57 3 …or equivalently 5 4 7 3 2 2 1 6 int main() { class X { int i = 1; private : auto z = [&i]( int y) { int & i; return i + y; }(3); public : return z; X( int & i): i(i) {} } int operator ()( int y) /*const*/ { godbolt.org/z/xazquF return i + y; } }; // potentially lots of lines of code int main() { int i = 1; auto z = X{i}(3); return z; } godbolt.org/z/3ycaAW
Q: What is the output of the program? 5 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University 7 6 1 12 / 57 4 3 2 #include <iostream> int main() { int i = 1; auto x = [i]() { return ++i; }; std::cout << i << x() << i; } godbolt.org/z/nv83nh
Q: What is the output of the program? 1 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University error: cannot assign to a variable captured by copy in a non-mutable lambda 7 6 12 / 57 5 4 3 2 #include <iostream> int main() { int i = 1; auto x = [i]() { return ++i; }; std::cout << i << x() << i; } godbolt.org/z/nv83nh
Q: What is the output of the program? 5 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University 7 6 1 13 / 57 4 3 2 #include <iostream> int main() { int i = 1; auto x = [i]() mutable { return ++i; }; std::cout << i << x() << i; } godbolt.org/z/Gs995r
13 / 57 6 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax 2 3 Nis Meinert – Rostock University 4 7 5 1 A: 121 #include <iostream> int main() { int i = 1; auto x = [i]() mutable { return ++i; }; std::cout << i << x() << i; } godbolt.org/z/Gs995r
Q: What is the output of the program? 5 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax Nis Meinert – Rostock University 7 6 1 14 / 57 4 3 2 #include <iostream> int main() { int i = 1; auto x = [&i]() mutable { return ++i; }; std::cout << i << x() << i; } godbolt.org/z/gEhwLt
14 / 57 6 Everything you (n)ever wanted to know about C++’s Lambdas – Syntax 2 3 Nis Meinert – Rostock University 4 7 5 1 A: 122 #include <iostream> int main() { int i = 1; auto x = [&i]() mutable { return ++i; }; std::cout << i << x() << i; } godbolt.org/z/gEhwLt
Q: What is the output of the program? 1 2 3 4 5 6 Nis Meinert – Rostock University Everything you (n)ever wanted to know about C++’s Lambdas – Syntax 15 / 57 #include <iostream> int main() { auto x = [i=0]() mutable { return ++i; }; std::cout << x() << x(); } godbolt.org/z/iLqPrn
Recommend
More recommend