Antern
Antern

Reputation: 43

Cannot pass lambda expression as reference

I have this code sample:

#include <iostream>

void
foo( int & value )
{
    value += 5;
}

template< class T >
void
foo( T value )
{
    value();
}

template < class T >
void bar( T & val )
{
    foo( val );
}

int main()
{

int i = 0;
bar( i );
std::cout << i << std::endl;
// prints: 5

bar( [](){ std::cout << "ok1" << std::endl; } );
// prints: ok1

[]()
{
    bar(
        [](){ std::cout << "ok2" << std::endl; } );
}();
// error:
/*
test.cpp(36) : error C2664: 'void bar<void(__cdecl *)(void)>(T &)' : cannot conv
ert argument 1 from 'void (__cdecl *)(void)' to 'void (__cdecl *&)(void)'
        with
        [
            T=void (__cdecl *)(void)
        ]

*/

}

Can someone explain why first time ("ok1") lambda converts successful, but in case of nesting ("ok2") it "cannot convert" ?

P.S. ofc it works well when I use "universal reference" argument in that template function, but I'm interesting of understanding.

Upvotes: 0

Views: 260

Answers (1)

Marius Bancila
Marius Bancila

Reputation: 16328

This works. Does it help you?

auto l = [](){ std::cout << "ok2" << std::endl; };
[&l]()
{
   bar(l);
}();

Upvotes: 1

Related Questions