(No #include's were used for this example, compiled on MacOS10.14, Eclipse IDE, with g++, options -O0 -g3 -Wall -c -fmessage-length=0)
Assuming this variable declaration:
int (*fun)(int);
This fails to compile with "invalid overload of std::toupper and std::tolower".
fun = (1 ? std::toupper : std::tolower); // ERROR, invalid overload
And this compiles OK:
if (1) { fun = std::toupper; // OK } else { fun = std::tolower; // OK }
std::toupper
(1 and 2) and std::tolower
(1 and 2) are overloaded. When determining the common type between them for the conditional operator (before the assignment to chr2fun
), which overloading should be used can't be determined.
You can use static_cast
to specify which one should be considered. (Presicely, to force the overload resolution happens at first respectively, then the trouble in determining the common type disappears.)
static_cast
may also be used to disambiguate function overloads by performing a function-to-pointer conversion to specific type
e.g.
chr2fun = (str2modus == STR2UP ? static_cast<int(*)(int)>(std::toupper) : static_cast<int(*)(int)>(std::tolower));
For the 2nd case, chr2fun
is assigned directly; the type of chr2fun
is explicit and the correct overloading would be selected in overload resolution.
(emphasis mine)
In all these contexts, the function selected from the overload set is the function whose type matches the pointer to function, reference to function, or pointer to member function type that is expected by target: the object or reference being initialized, the left-hand side of the assignment, function or operator parameter, the return type of a function, the target type of a cast, or the type of the template parameter, respectively.
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