Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deleting overloaded function. C++11. Call of overloaded ... is ambiguous

Tags:

c++

c++11

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?

like image 588
Adam Stepniak Avatar asked Dec 28 '17 17:12

Adam Stepniak


2 Answers

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 deleteing 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.

like image 153
vsoftco Avatar answered Nov 12 '22 17:11

vsoftco


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.

like image 29
Chris Uzdavinis Avatar answered Nov 12 '22 16:11

Chris Uzdavinis