Reputation: 683
Using a template type within the parameters of a function passed as argument (either as std::function or as a function pointer) makes the compiler unable to deduce the type when the function is passed as a lambda (see code below). Interestingly this works if the function is not a lambda.
Is there any way to achieve this? I've tried the following code with Visual Studio 2017 and GCC 7.4 and both fail, so it's unlikely to be a compiler bug and probably there is a reason for this behaviour.
#include <iostream>
#include <functional>
template <typename T>
void collide(void (*callback)(T)) // or std::function<void(T)> callback
{
callback(42);
}
int main() {
// doesn't compile: "could not deduce template arguments"
collide([](int a) {
std::cout << a << std::endl;
});
}
Upvotes: 1
Views: 103
Reputation: 310930
Try to use the following call
collide( *[](int a) {
std::cout << a << std::endl;
});
to convert the lambda to a pointer to a function explicitly.
Here is a demonstrative program.
#include <iostream>
template <typename T>
void f( void ( *fn )( T ) )
{
fn( 42 );
}
void g( int x )
{
std::cout << "g( " << x << " );\n";
}
int main()
{
f( g );
f( *[]( int x ) { std::cout << "main::lambda( " << x << ");\n"; } );
}
Its output is
g( 42 );
main::lambda( 42);
Upvotes: 3