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 classX
is defined in global scope; the notationX::f
specifies that the functionf
is a member of classX
and in the scope of classX
. In the function definition, the parameter typeT
refers to the typedef memberT
declared in classX
and the default argument count refers to the static data member count declared in classX
. ]
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;
精彩评论