Reputation: 8293
In gcc 4.5, the following code compiles and works as expected with -std=c++0x
,
#include <stdio.h>
template<typename H>
void caller(H h)
{
h();
}
int main()
{
auto c = [](){ printf("A\n"); };
caller(c);
caller([](){ printf("B\n"); });
return 0;
}
Prints,
A
B
However, if caller
is defined to take a reference,
template<typename H>
void caller(H &h)
{
h();
}
The compiler complains,
test.cpp: In function ‘int main()’:
test.cpp:61:34: error: no matching function for call to ‘caller(main()::<lambda()>)’
test.cpp:52:6: note: candidate is: void caller(H&) [with H = main()::<lambda()>]
Why?
This seems to break the idea of lambdas providing value semantics for functions, but moreover it means I can't write certain small functions inline which is a bit annoying.
(Is this fixed in newer versions of gcc? I haven't had a chance to test.)
Edit: I just discovered the following actually works:
template<typename H>
void caller(H *h)
{
(*h)();
}
int main()
{
auto c = [](){ printf("A\n"); };
caller(&c);
caller(&([](){ printf("B\n"); }));
}
I didn't think I'd be able to take the address of a temporary like that. Maybe that sort of solves the problem, though annoying to require users of the function to pass in the address of the closure instead of a convenient reference.
Upvotes: 4
Views: 778
Reputation: 157344
You're trying to pass a temporary by non-const reference. That won't work for any type.
Pass the lambda by const reference instead.
Upvotes: 6