struct add_n_simple {
int _n;
int invoke(int x) const { return _n + x; }
};
add_n_simple
can be used as a function which adds n
to any value passed to invokeadd_n_simple add_s{5};
cout << add_s.invoke(10) << "\n";
operator()
, instead of invoke
struct add_n_function {
int _n;
int operator()(int x) const { return _n + x; }
};
add_n_function add_f{5};
cout << add_f(10) << "\n";
struct add_n_function {
int _n;
int operator()(int x) const { return _n + x; }
add_n_function add_f{5};
{
auto add_n_lambda = [_n = 5](int x) -> int { return _n + x; };
cout << add_n_lambda(10) << "\n";
}
decltype(add_n_lambda)
[_n = 5]
(int x) -> int { return _n + x; }
add_n_lambda
auto
(not void
){
int n = 42;
auto return_n = [n]{ return n; };
cout << return_n() << '\n';
}
capture types are deduced
[]
no capture, convertible to function pointer
[=]
capture-default any referenced local variable by value (copy)
[&]
capture-default any referenced local variable by reference
[x]
captures x by value
[&x]
captures x by reference
[_x = expression]
capture _x
as the value of expression
[=, &x, _x = expression]
defaults can be mixed with other captures
captured values are fixed when lambda is created, not at invocation
{
int x = 10;
int y = 20;
auto ex1 = [=]{ return x + y; };
auto ex2 = [&]{ x *= y; };
auto ex3 = [x, y]{ return x + y; };
auto ex4 = [x, &y]{ y += x; };
auto ex5 = [_x = ex1()]{ return _x; };
cout << ex1() << '\n';
ex2();
cout << ex3() << '\n';
ex4();
cout << ex5() << '\n';
cout << "x:" << x << '\n';
cout << "y:" << y << '\n';
}
[this]
captures current object by reference[*this]
captures current object by-value (C++17)[args...]
capture pack expansion by value[&args...]
capture pack expansion by referenceauto
to create a generic lambdaauto...
struct add_t {
template <class T, class U>
auto operator()(T x, U y) const {
return x + y;
}
};
{
add_t add;
cout << add(5, 10.3) << '\n';
}
{
auto add = [](auto x, auto y) { return x + y; };
cout << add(5, 10.3) << '\n';
}
auto&&
is a forwarding-referencestruct accumulate_t {
int _value;
int operator()(int x) {
_value += x;
return _value;
}
};
{
accumulate_t accumulate{5};
cout << accumulate(10) << '\n';
cout << accumulate(3) << '\n';
}
{
auto accumulate = [_value = 5](int x) mutable {
_value += x;
return _value;
};
cout << accumulate(10) << '\n';
cout << accumulate(3) << '\n';
}
struct print_all_t {
template <class... Args>
void operator()(const Args&... args) const {
(void)initializer_list<int>{((cout << args << '\n'),0)...};
}
};
{
print_all_t print_all;
print_all(1, 10.5, "Hello!");
}
{
auto print_all = [](const auto&... args) {
(void)initializer_list<int>{((cout << args << '\n'), 0)...};
};
print_all(1, 10.5, "Hello!");
}
std::function<>
can hold any callable object with a matching signaturestruct lambda_member {
size_t _count = 0;
function<void(const string&)> _lambda = [_n = _count](const auto& x) {
for(auto n = _n; n != 0; --n) cout << x << '\n';
};
};
lambda_member object{4};
object._lambda("Hello");
function
object._lambda = [](const auto& x) {
cout << "I heard you the first time, " << x << '\n';
};
object._lambda("World!");
template <class F, class... Args>
auto bind_once(F&& f, Args&& ...args) {
return bind([_f = forward<F>(f)](auto& ...args) mutable {
return move(_f)(move(args)...);
}, forward<Args>(args)...);
}
unique_ptr<int> sink(unique_ptr<int>&& x) { return move(x); }
auto bound = bind_once(sink, make_unique<int>(42));
cout << *bound() << '\n';
bind_once()
to be expressed as:template <class F, class... Args>
auto bind_once(F&& f, Args&& ...args) {
return [_f = forward<F>(f), _args = forward<Args>(args)...] () mutable {
return move(_f)(move(_args)...);
};
}
Find a place in your current project for a function is passed to and standard algorithm or container
Replace it with a lambda expression
Report the example and your thoughts on the wiki
An example...
// Find first position, p, in v, where *p < x
auto p = find_if(begin(v), end(v), [&](const auto& a){ return a < x; });