I wonder why a static_cast
from int (*)(const int&)
to type int (*)(int&)
is illegal. If I have a function pointer that technically allows accepting an int&
but want to assign to it a function which voluntarily waives the permission to modify the pointed-to value, shouldn't it behave just as a special case of a function that in principle could?
In other words, given that I can pass an arbitrary int&
to an int (*)(const int&)
function, is there a deeper reason in the standard why the latter can't be considered a special case of int (*)(int&)
and assigned to such variable?
M(!W)E:
int g(const int& q) {
return q;
}
int main() {
int (*f)(int&) = static_cast<int(*)(int&)>(g); // breaks
int x = 1;
return f(x);
}
[...] is there a deeper reason in the standard why [...]
These questions are typically impossible to answer. Maybe nobody thought of it as a worthwhile thing to look into. C++ in general has limited support for covariance and contravariance. There are plenty of other safe conversions that are potentially possible, not just qualifying the references.
For instance, a function pointer like Animal*(*)(Dog*)
could be initializeable from both Animal*(*)(Animal*)
and Dog*(*)(Dog*)
. But today, neither conversion is supported.
So the real answer is probably: write a proposal.
However, in this case, we can still accomplish the desired behavior through a clearly underappreciated rule: Almost Always Lambda. We know, by name, the function we want to use, and lambdas without capture (which we don't need) can be converted into function pointers:
int (*f)(int&) = [](int& i) { return g(i); };
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