Search code examples
c++namespacesscopeoverloadingusing-declaration

Does a using-declaration only import overloads declared above the using-declaration?


For example, GCC and clang both fail to compile the following code:

struct S {};

namespace N
{
    void g(S);
}

using N::g;

namespace N
{
    void g(int);
}

int main()
{
    g(0);
}

with the error:

test.cpp: In function 'int main()':
test.cpp:17:8: error: could not convert '0' from 'int' to 'S'
     g(0);
        ^

suggesting that the using-declaration only imports the overloads declared above the point where the using-declaration appears, not ones that may appear later (but before the use of the name).

Is this behaviour correct?


Solution

  • Is this behaviour correct?

    Yes, this behavior is correct and is well defined as per the c++ standard.

    The relevant section is § 7.3.3.11 of C++11 standard:

    The entity declared by a using-declaration shall be known in the context using it according to its definition at the point of the using-declaration. Definitions added to the namespace after the using-declaration are not considered when a use of the name is made.

    [ Example:    
        namespace A {
            void f(int);
         }
        using A::f; // f is a synonym for A::f;
        // that is, for A::f(int).
        namespace A {
            void f(char);
        }
        void foo() {
            f(’a’); // calls f(int),
        } // even though f(char) exists.
        void bar() {
            using A::f; // f is a synonym for A::f;
            // that is, for A::f(int) and A::f(char).
            f(’a’); // calls f(char)
        }
     —end example ]