Search code examples
c++overloadinglanguage-lawyername-lookup

Function overload outside class not seen


Consider following code snippet:

enum class Bar {
    A
};

void foo(Bar) {}

struct Baz {
    void foo() {
        foo(Bar::A);
    }
};

It fails to compile, the message from gcc 9.2 is:

:12:19: error: no matching function for call to 'Baz::foo(Bar)'
 12 |         foo(Bar::A);
    |              

I don't suspect it is a bug since clang 10 also fails. I have two questions regarding this situation:

  1. Where does standard define bahaviour for such overloads?

  2. What are the possible reasons that compiler behaviour is specified that way?

live example


Solution

  • According to the rule of unqualified name lookup, from the standard, [basic.lookup.unqual]/1,

    (emphasis mine)

    In all the cases listed in [basic.lookup.unqual], 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.

    That means the name foo is found at the class scope (i.e. the Baz::foo itself), then name lookup stops; the global one won't be found and considered for the overload resolution which happens later.

    About your 2nd question, functions can't be overloaded through different scopes; which might cause unnecessary confusion and complexity. Consider the following code:

    struct Baz {
        void foo(int i) { }
        void foo() {
            foo('A');
        }
    };
    

    You know 'A' would be converted to int then passed to foo(int), that's fine. If functions are allowed to be overloaded through scopes, if someday a foo(char) is added in global scope by someone or library, behavior of the code would change, that's quite confusing especially when you don't know about the adding of the global one.