I have next code:
void f(int){}
struct A
{
void f()
{
f(1);
}
};
This code is not well-formed with the error message (GCC): error: no matching function for call to ‘A::f(int)’
or (clang) Too many arguments to function call, expected 0, have 1; did you mean '::f'?
Why do I need to use ::
to call the non-member function with the same name as the member function, but with different signature? What is the motivation for this requirement?
I think the compiler should be able to figure it out I want to call the non-member function as the signature is different (clang even puts that in the error message!).
Please don't mark this as duplicate - it is a different question from this Calling in C++ a non member function inside a class with a method with the same
The answer is YES.
A non-member function always appears outside of a class. The member function can appear outside of the class body (for instance, in the implementation file). But, when you do this, the member function must be qualified by the name of its class. This is to identify that that function is a member of a particular class.
A constructor is a member function that has the same name as that of the class.
Use a nonmember function if you don't need type conversion in the first argument or don't need access to private data. Use a member function if you do need access to private data. And then each user can decide how to call it. This is what's actually needed.
Why do I need to use :: to call the non-member function with the same name as the member function, but with different signature
Because those are the rules. Names in a nested scope hide entities with the same name in a wider scope.
What is the motivation for this requirement?
Consider the case where a member function calls another member with a signature that doesn't quite match:
struct A {
void f(double);
void g() {f(42);} // requires int->double conversion
};
Now suppose someone adds an unrelated function in the surrounding namespace
void f(int);
If this were included in the set of overloads within the scope of A
, then suddenly the behaviour of A::g
would change: it would call this instead of A::f
. Restricting the overload set to names in the narrowest available scope prevents this kind of unexpected breakage.
As you (and your helpful compiler) say, the outer name is still available (with qualification) if you need it.
The compiler performs unqualified name lookup, for f
, specified in §3.4.1 [basic.lookup.unqual] (thankfully, there's no ADL here):
1 In all the cases listed in 3.4.1, the scopes are searched for a declaration in the order listed in each of the respective categories; name lookup ends as soon as a declaration is found for the name. If no declaration is found, the program is ill-formed.
8 For the members of a class
X
, a name used in a member function body, in a default argument, in an exception-specification, in the brace-or-equal-initializer of a non-static data member (9.2), or in the definition of a class member outside of the definition of X, following the member’s declarator-id, shall be declared in one of the following ways:
- before its use in the block in which it is used or in an enclosing block (6.3), or
- shall be a member of class
X
or be a member of a base class ofX
(10.2), or- if
X
is a nested class of classY
(9.7), shall be a member ofY
, or shall be a member of a base class ofY
(this lookup applies in turn toY
’s enclosing classes, starting with the innermost enclosing class), or- if
X
is a local class (9.8) or is a nested class of a local class, before the definition of classX
in a block enclosing the definition of classX
, or- if
X
is a member of namespaceN
, or is a nested class of a class that is a member ofN
, or is a local class or a nested class within a local class of a function that is a member ofN
, before the use of the name, in namespaceN
or in one ofN
’s enclosing namespaces.
Name lookup stops as soon as a declaration is found. So once it finds the member f()
at the second bullet point it stops and never searches elsewhere.
Rejection of nonviable functions are done after name lookup, at overload resolution.
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