Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to declare the template argument for an overloaded function

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading