There is global function (just example):
void func( int i )
{
std::cout << i + 100 << std::endl;
}
I assume that calling this function with char argument does not make any sense so I use delete:
void func(char) = delete;
So I expect that following calls should be possible:
func(1);
func(3.1);
func(true);
And call with char argument should be forbiden:
func('a');
But that is not true. When calling func('a')
I get as expected:
error: use of deleted function ‘void func(char)’
But during calling func(2.3)
I get:
error: call of overloaded ‘func(double)’ is ambiguous
Why do I get this error? Without deleting function with char arguments double was converted to int and func(int) was called, why now it is forbidden?
When you call
func(2.3)
you pass a double
to the function. The list of candidates contains both func(int)
and func(char)
, as overload resolution happens before delete
kicks in:
If the function is overloaded, overload resolution takes place first, and the program is only ill-formed if the deleted function was selected Ref: cppreference.com, see Avishai's answer for precise standard quotes.
Now double
can be converted both to char
and int
, hence the ambiguity.
Without deleting function with char arguments double was converted to int and func(int) was called, why now it is forbidden?
You get an ambiguity error even without delete
ing the char
version, see live here. Of course if you only define the func(int)
, then there will be no ambiguity so double
will happily be converted to an int
.
Any time a non-exact match is passed in for a function parameter, a conversion must be done. When you have two functions, regardless if one is deleted, they still participate in overload resolution. The compiler picks the best match, then either generates a call to it, or fails if the function is inaccessible or deleted.
For overload resolution to work, it makes a set of candidate functions then sees which has the shortest conversion path to the set of parameters. As far as the rules go, all builtin numeric types are an "equal" conversion. Therefore, if you call with 2.5, which is a double, it must convert and can convert equally to a char OR to an int, with the same ranking, so the call is ambiguous.
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