开发者

Defining namespaced member vs free functions without qualification

开发者 https://www.devze.com 2023-03-30 14:53 出处:网络
I sometimes declare classes in nested namespaces and when it comes to defining their member functions, I prefer not to have to qualify each one with thesenested namespace names, especially if they are

I sometimes declare classes in nested namespaces and when it comes to defining their member functions, I prefer not to have to qualify each one with these nested namespace names, especially if they are long-ish.

Adding "using namespace " (or, for more precise targetting, "using ::SomeClass") before I define the member functions seems to obviate the need to qualify each definition, but I can't find anywhere in the spec that guarantees this, and I'm worried that it might be a behaviour that only works with GCC. I note that there doesn't appear to be a similar mechanism for skipping the need to add the qualifiers when defining free functions(?).

As an example of what I mean:

H开发者_如何学编程eader:

// example.h
namespace SomeNamespace
{
    class SomeClass
    {
    public:
        void someMemberFunction();
    };

    void someFreeFunction();
};

Implementation:

// example.cpp
#include "example.h"

using namespace SomeNamespace;

void SomeClass::someMemberFunction()
{
    // OK: seems to define SomeNamespace::SomeClass::someMemberFunction(),
    // even though we didn't qualify it with SomeNamespace::
}

void someFreeFunction()
{
    // Not what we wanted; declares and defines ::someFreeFunction(), not
    // SomeNamespace::someFreeFunction() (quite understandably)
}

int main()
{
    SomeClass a;
    a.someMemberFunction(); // Ok; it is defined above.
    SomeNamespace::someFreeFunction(); // Undefined!
    return 0;
}

So my question: is the above way of definining SomeClass::someMemberFunction() legal, and where in the spec is this mentioned? If legal, is it advisable? It certainly cuts down on clutter! :)

Many thanks :)


Perhaps I'm getting this wrong but if you have:

// example.h
namespace SomeNamespace
{
    class SomeClass
    {
    public:
        void someMemberFunction();
    };

    void someFreeFunction();
};

You can also simply write:

#include "example.h"

// example.cpp
namespace SomeNamespace
{
    void SomeClass::someMemberFunction()
    {
    }

    void someFreeFunction()
    {
    }
}


When you define a member-function, the compiler realizes that it is a member-function that must belong to a previously declared class, so it looks that class up, as specified in Section 9.3.5 of the standard:

If the definition of a member function is lexically outside its class definition, the member function name shall be qualified by its class name using the :: operator. [Note: a name used in a member function definition (that is, in the parameter-declaration-clause including the default arguments (8.3.6), or in the member function body, or, for a constructor function (12.1), in a mem-initializer expression (12.6.2)) is looked up as described in 3.4. ] [Example:

struct X {
    typedef int T; 
    static T count; 
    void f(T); 
}; 

void X::f(T t = count) { }

The member function f of class X is defined in global scope; the notation X::f specifies that the function f is a member of class X and in the scope of class X. In the function definition, the parameter type T refers to the typedef member T declared in class X and the default argument count refers to the static data member count declared in class X. ]

Basically, what you are doing is fine. However, there is another (preferable) way to cut down on the clutter when using nested namespaces, or namespaces with long names (or both) - define an alias:

namespace short_name = averylong::nested::namespacename;
0

精彩评论

暂无评论...
验证码 换一张
取 消