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);
CodePudding user response:
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);