Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why calling a non-member function with the same name as a member function generates an error

Tags:

c++

c++11

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

like image 532
Mircea Ispas Avatar asked Sep 17 '14 09:09

Mircea Ispas


People also ask

Can we call a non-member function inside a class?

The answer is YES.

What is the difference between member function and non-member function?

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.

Is a member function with the same name as the class?

A constructor is a member function that has the same name as that of the class.

When would you use a non-member function?

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.


Video Answer


2 Answers

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.

like image 144
Mike Seymour Avatar answered Oct 28 '22 11:10

Mike Seymour


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 of X (10.2), or
  • if X is a nested class of class Y (9.7), shall be a member of Y, or shall be a member of a base class of Y (this lookup applies in turn to Y’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 class X in a block enclosing the definition of class X, or
  • if X is a member of namespace N, or is a nested class of a class that is a member of N, or is a local class or a nested class within a local class of a function that is a member of N, before the use of the name, in namespace N or in one of N’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.

like image 41
T.C. Avatar answered Oct 28 '22 11:10

T.C.