[SOLVED] How to declare the template argument for an overloaded function

Issue

I have a fairly big project that, regarding this question,
I can summarize with
this structure:

void do_something()
{
    //...
}

template<typename F> void use_funct(F funct)
{
    // ...
    funct();
}

int main()
{
    // ...
    use_funct(do_something);
}

All is working ok until someone (me) decides to reformat a little
minimizing some functions, rewriting
as this minimum reproducible example:

void do_something(const int a, const int b)
{
    //...
}

void do_something()
{
    //...
    do_something(1,2);
}

template<typename F> void use_funct(F funct)
{
    // ...
    funct();
}

int main()
{
    // ...
    use_funct(do_something);
}

And now the code doesn’t compile with
error: no matching function for call
where use_funct is instantiated.

Since the error message was not so clear to me
and the changes were a lot I wasted a considerable
amount of time to understand that the compiler
couldn’t deduce the template parameter
because do_something could now refer to
any of the overloaded functions.

I removed the ambiguity changing the function name,
but I wonder if there’s the possibility to avoid
this error in the future not relying on template
argument deduction.
How could I specify in this case the template argument for do_something(), possibly without referring to a function pointer?
I haven’t the slightest idea to express explicitly:

use_funct<-the-one-with-no-arguments->(do_something);

Solution

You can wrap the function in a lambda, or pass a function pointer after casting it to the type of the overload you want to call or explicitly specify the template parameter:

use_funct([](){ do_something (); });
use_funct(static_cast<void(*)()>(do_something));
use_funct<void()>(do_something);

Wrapping it in a lambda has the advantage, that it is possible to defer overload resolution to use_func. For example:

void do_something(int) {}

void do_something(double) {}

template<typename F> void use_funct(F funct) {   
    funct(1);    // calls do_something(int)
    funct(1.0);  // calls do_something(double)
}

int main() {   
    use_funct([](auto x){ do_something (x); });
}

[…] possibly without referring to a function pointer?

I am not sure what you mean or why you want to avoid that. void() is the type of the function, not a function pointer. If you care about spelling out the type, you can use an alias:

using func_type = void();
use_funct<func_type>(do_something);

Answered By – 463035818_is_not_a_number

Answer Checked By – Katrina (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published.