Daily bit(e) of C++ | default-constructible lambdas

Šimon Tóth
1 min readJun 6, 2024

--

Daily bit(e) of C++ #478, C++20 default-constructible and copy-assignable support for non-capturing lambdas.

C++20 introduced a significant change to lambdas without capture. The autogenerated unique type is now default-constructible and copy (and move) assignable.

While the previous behaviour made sense for lambdas with captures and conceptually (each lambda is inherently an instance of its autogenerated type), it also made lambdas awkward to use as arguments to generic code.

#include <map>

// Using a function object
struct Cmp {
bool operator()(int l, int r) const {
return l < r;
}
} cmp;

std::map<int,int,Cmp> a; // OK
std::map<int,int,decltype(cmp)> b; // OK
a = b; // OK

// Same logic using a lambda
auto lcmp = [](int l, int r) { return l < r; };

std::map<int,int,decltype(lcmp)> c(lcmp); // OK
// pre-C++20 we have to copy-construct the comparator

std::map<int,int,decltype(lcmp)> d; // Wouldn't compile pre-C++20
// pre-C++20 delctype(lcmp) isn't default constructible

c = d; // Wouldn't compile pre-C++20
// pre-C++20 decltype(lcmp) isn't copy-assignable

Open the example in Compiler Explorer.

--

--

Šimon Tóth

20 years worth of Software Engineering experience distilled into easily digestible articles.