Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ function overloading resolution involving pass-by-value, reference and constant reference [duplicate]

Suppose I define some function f with the following 3 signatures in C++:

void f(int x) {}
void f(int& x) {}
void f(const int& x) {}

These functions can coexist since they differ in the types of the arguments.

Now I run the following code:

int main {
   int i = 3;
   const int ci = 4;

   f(3);
   f(i);
   f(ci);
}

How does C++ know which overloaded function to call in this specific case ? What are rules in general ( best practice ? ) for writing overloaded functions in C++ as to avoid ambiguity. Does the current C++14 standard specify any specific rules ?

like image 884
Mutating Algorithm Avatar asked Dec 11 '22 18:12

Mutating Algorithm


2 Answers

All three calls are ambiguous, so the program won't compile.

f(3);

This could use either the first or third overload. They are equally good, so the call is ambiguous.

f(i);

This could use the first, second, or third overload. The second is better than the third; binding to int& is preferred over binding to const int& when it's possible. So it's fine to overload on cv-qualification in this way. But there is an ambiguity between the first and second overloads.

f(ci);

This could use the first or third overload. Again, they are equally good, so the call is ambiguous.


The standard precisely specifies the rules of overload resolution. They are very complicated, so it is a bad idea to overload functions in a way that makes it hard for the reader to tell which overload will be called. You can find the rules here.

like image 138
Brian Bi Avatar answered Feb 02 '23 00:02

Brian Bi


You cannot overload:

void f(int x) {}
void f(const int& x) {}

Given those, the compiler won't be able to disambiguate the following call:

f(10);

You cannot overload:

void f(int x) {}
void f(int& x) {}

Given those, the compiler won't be able to disambiguate the following call:

int i = 0;
f(i);

You can overload:

void f(int& x) {}
void f(int const& x) {}

Given those, you can use:

int i = 0;
f(i);    // Resolves to f(int&)
f(10);   // Resolves to f(int const&)
like image 44
R Sahu Avatar answered Feb 01 '23 23:02

R Sahu