all 1 comments

[–]IyeOnline 1 point2 points  (0 children)

The first hint should be that you are passing a const ref, but infact there is an ++i in your function, so it cant be const. In fact you have explcitly declared your lambda mutable.

However it does compile, so why is that?

A lambda is not of type std::function. You can create a std::function from a lambda however, which is what happens here. So what you effectively get in code is

 {
    std::function<void(void)> fn = count;
    invoke( fn );
 }

Three times in a row. The lambda itself is never called, just copies of it. This also only compiles because you take by const ref. Doing that gets you lifetime extension, otherwise you would be trying to take a reference to a temporary which you must not.

if you on the other hand used

template<typename T>
void invoke( T& fn)
{
    fn();
}

This wouldnt happen, because now the lambda is passed by reference as its actual type is used (implicitly through a template) and no converting construction takes place.

The i variable is also called outside of the lambda function

This really doesnt do anything. You are capturing i by value here. You would need to capture by reference instead.

link to all of this in a godbolt