Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 376
Igor G Avatar asked Nov 28 '25 19:11

Igor G


2 Answers

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";
    }
}
like image 93
BoBTFish Avatar answered Dec 01 '25 07:12

BoBTFish


Quoting C++17 (n4659) 12.2.1 [class.mfct]/1:

A member function definition that appears outside of the class definition shall appear in a namespace scope enclosing the class definition.

This means it must be defined in the namespace which contains the class, or any parent namespace of that namespace. In your case, it's defined in the global namespace, which does indeed enclose (indirectly) the class definition.

like image 28
Angew is no longer proud of SO Avatar answered Dec 01 '25 07:12

Angew is no longer proud of SO



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!