Inside the method N::f(int i)
, the call f(m)
is interpreted by the compiler as a call to N::f(int)
(because you're inside the struct N
and have a method with that name). The compiler looks for a function named f
that takes an M
as a parameter in the current scope, but only sees N::f(int)
which is not compatible with f(M&)
.
This is a case of name hiding in C++. The member function N::f(int)
hides the global f(M&)
function within its scope. As a result, when you try to call f(m)
, the compiler doesn’t look at the global scope. It only considers N::f(int)
, which doesn’t match.
Use the scope resolution operator to refer to the global function explicitly:
::f(m); // This calls the global f(M&) function
If it is not resolved even after explicitly calling the global function, you are probably using an old C++ compiler, because compilers supporting C++14 to C++23 execute this without any errors.