In the code below, it looks quite obvious that the function definition for myFn
with two arguments should come from namespace N
. But the compiler fails to compile it. Is it a compiler (g++ 8.3) limitation, or imposed by the C++ standard?
#include <bits/stdc++.h>
using namespace std;
namespace N
{
// Same name function exists in class A
void myFn(int a, int b)
{
cout << a << ' ' << b << endl;
}
}
using namespace N;
class A {
public:
void myFn(int a)
{
#ifdef FINE
// Explicitly specify where should myFn definition come from
N::myFn(a, a);
#else
myFn(a, a);
#endif
}
};
int main()
{
A a;
a.myFn(3);
return 2;
}
It generates this error message when one overload is more specific for one argument's data type while another overload is more specific for another argument's data type.
Function overloading is a feature that allows us to have same function more than once in a program. Overloaded functions have same name but their signature must be different.
The process of selecting the most appropriate overloaded function or operator is called overload resolution. Suppose that f is an overloaded function name. When you call the overloaded function f() , the compiler creates a set of candidate functions.
Function overloading is a feature of object-oriented programming where two or more functions can have the same name but different parameters. When a function name is overloaded with different jobs it is called Function Overloading.
It's intended. Name lookup stops at the scope where the name is found. The mechanism makes sure your code behaves the same even if functions are added or removed from the enclosing scopes.
Otherwise, changing N
's members would risk breaking enclosed classes and namespaces. Consider the potential disasters if one adds a free function that is a better match in overload resolution compared to another class member. If it wasn't ignored, the behavior of the class could change by accident!
This example should illustrate the issue:
namespace ns {
// void foo(int) { std::terminate(); }
struct C {
void foo(char) {}
C() {
foo(0);
}
};
}
Under the current rules, uncommenting foo
will have no adverse effects. But if name lookup did consider it, because 0 is an int
and must be converted to a char
, constructing a C
would abort the program! That's drastic and easy to spot. But in a real 100M LOC program, misbehaving name lookup could cause bugs that are much more sinister and harder to catch.
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