Search code examples
c++c++11namespacesusing-directivesname-lookup

Class member function defined outside its namespace


The following code compiles perfectly with the latest MSVC, GCC and CLang available at godbolt online compiler explorer site. I wonder why:

namespace ns
{
    struct Test
    {
        void foo();
    };
}

using namespace ns;

// Alert! Member function defined outside its namespace!
void Test::foo()
{
}

int main()
{
    ns::Test   obj;
    obj.foo();
    return 0;
}

cppreference claims that if a member function is defined outside its class, then it must be defined at the namespace of that class. See the very top of the cppreference page about member functions.

But still, the compilers accept the code. It's really unlikely that all three independent compilers have the same bug, right? So, is there a good reason behind them accepting such code?


Solution

  • 12.2.1 Member functions [class.mfct]

    A member function may be defined (11.4) in its class definition, in which case it is an inline member function (10.1.6), or it may be defined outside of its class definition if it has already been declared but not defined in its class definition. A member function definition that appears outside of the class definition shall appear in a namespace scope enclosing the class definition.

    This does not mean the definition must appear in the immediately surrounding scope. It can appear in any enclosing namespace, even if that is several layers up.

    However, this would be illegal:

    namespace a {
        struct X {
            void Y();
        };
    }
    namespace b { // not an enclosing namespace
        void X::Y()
        {
            std::cout << "Do a thing!\n";
        }
    }