2
struct setup_entry 
{
    template< typename T >
    void Disable( bool(*p)(T*) ) { ... }
}

Calling Disable:

setup_entry X;

Case 1: X.Disable( [](int*)->bool{...} );        //FAIL to deduce T
Case 2: X.Disable<int>( [](int*)->bool{...} );   //OK   to deduce T

I would like to use case 1. (Easier for the user)

Any ideas?


The simplified final solution for the record was to do this:

template< typename T >
void Disable( T&& Callback )
{ 
   auto p = +Callback;
   ...
}
Nickreal03
  • 65
  • 7
  • 2
    Unrelated to your problem, but I would recommend against using function pointers as arguments. Either use templates (as all of the standard library does) or use `std::function`. That way you can use *any* callable object (like for example lambdas *with* captures). By the way, unless you need `T` inside your function, using a template for the function object itself would also solve your problem. – Some programmer dude Feb 07 '19 at 11:39

2 Answers2

4

You can't do that because implicit conversion (from lambda to function pointer) won't be considered in template argument deduction; T can't be deduced.

Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.

If you want to stick to auto type deduction, you can convert the lambda to function pointer explicitly, e.g.

X.Disable(+[](int*)->bool{...} ); 
//        ^

Or

X.Disable(static_cast<bool(*)(int*)>([](int*)->bool{...}));
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
1

First you should know that the type of [](int*) -> bool {...} is not just bool(int*) or bool(*)(int*); it is a unique closure type convertible to bool(*)(int*).

And this type is not deducible in this context.

A solution: explicitly do the conversion.

X.Disable( static_cast<bool(*)(int*)>([](int*) -> bool {...}) );

Better solution: as @Some programmer dude says, use a template or use std::function. For example:

template <typename F>
void Disable(F f)
{
    static_assert(std::is_invocable_r_v<bool, F, int*>, "your message here"); // if you want to ensure that the function is actually valid
    // ...
}

Or:

void Disable(std::function<bool(int*)> f) { ... }
L. F.
  • 19,445
  • 8
  • 48
  • 82