Lambdas are lambda object instances that created from the lambda object definition. When lambdas are assigned to another variable, they get copied. For example:

#include <iostream>
 
int main()
{
    int i{0};
 
    auto count{[i]() mutable
               {
                   return ++i;
               }};
 
    std::cout << count() << '\n';
 
    auto anotherCount{count};
 
    std::cout << count() << '\n';
    std::cout << anotherCount() << '\n';
 
    return 0;
}

When anotherCount is initialized with count, it gets count’s copy with its current state. So, anotherCount() gives 2 because i was 1.

Similarly, if lambdas are passed to functions, if passing involves copy, functions would get copied lambda objects.

For example:

#include <iostream>
#include <functional>
 
void myInvoke(const std::function<int()> &fn)
{
    std::cout << fn() << '\n';
}
 
int main()
{
    int i{0};
 
    auto count{[i]() mutable
               {
                   return ++i;
               }};
 
    myInvoke(count);
    myInvoke(count);
    myInvoke(count);
 
    return 0;
}

When this program is executed, we get following:

1
1
1

This is because every time we invoke myInvoke with count, lambda type gets implicitly converted to std::function which creates lambda copy and assigns to the parameter.

References

  1. https://www.learncpp.com/cpp-tutorial/lambda-captures/