I'm trying to call an overloaded function which operates on function pointers that have parameters with default values.
void originalFunction1 (int a = 0) {printf("I'm #1 and a is %d",a);}
void originalFunction2 () {printf("I'm #2");}
void overloadedFunction (void (*fptr)(void))
{
fptr();
}
void overloadedFunction (void (*fptr)(int))
{
overloadedFunction( (void(*)(void)) fptr);
}
int main()
{
overloadedFunction(originalFunction1);
overloadedFunction(originalFunction2);
// output is:
// I'm #1 an a is -1073743272
// I'm #2
}
As the answers to this question points out, default values are not part of the function signature and also can't be repeated during the (function pointer -) parameter definition. As my example shows, they can be cast away for calling, but they will then not be initialized to their default value.
Is there any way to work around this?
I can't modify the original function but I know the default value. I can modify both the main overloaded function as well as the redirects. The fptr's will always only be called without parameters. In reality, there are more overloaded functions as also the return type differs, but I can cast that away more easily.
Yes, it can. This is purpose of casting function pointers, just like usual pointers. We can cast a function pointer to another function pointer type but cannot call a function using casted pointer if the function pointer is not compatible with the function to be called.
All the parameters of a function can be default parameters.
Default function parameters allow named parameters to be initialized with default values if no value or undefined is passed.
Yes, it is correct that you can assign a default value to the parameter before calling the function, which results in you not needing to pass an argument when calling the function. The default parameter is however always overridden if you pass a value to the function.
The short answer is no. The cast is legal, but the only thing you can do with the results is to cast them back to the orginal type. Default arguments do not change the signature of the function. They only enter into account at the call site, where they are passed if the client doesn't provide an argument. The function itself is always called with the full set of arguments, which it clearly won't be if you call it through the results of the cast.
The usual answer here, if you have control of the sources, is to use overloading instead of default arguments. (I have heard arguments that you should always use overloading instead of default arguments.) So
void originalFunction1( int a ) { ... }
void originalFunction1() { originalFunction1( 0 ); }
instead of what you have.
Alternatively, you might be able to play games with templates:
template <typename FunctionPtr>
void overloadedFunction( FunctionPtr fptr )
{
fptr();
}
I'd prefer the first solution if you can use it, however.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With