定义命名空间成员与自由功能,无需限定 [英] Defining namespaced member vs free functions without qualification

查看:96
本文介绍了定义命名空间成员与自由功能,无需限定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有时在嵌套命名空间中声明类,并且在定义它们的成员函数时,我不喜欢使用这些嵌套的命名空间名称来限定每个类,特别是如果它们是long-ish。



在我定义成员函数之前添加using namespace(或者,为了更精确的定位,使用some :: SomeClass)似乎不需要限定每个定义,但是我找不到在规范中的任何地方,保证这一点,我担心,它可能是一个行为,只适用于GCC。我注意到,似乎没有类似的机制,当定义自由函数(?)时跳过需要添加限定符。



作为一个例子,意思是:



标题:

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

void someFreeFunction();
};实施:

  

code> // example.cpp
#includeexample.h

使用命名空间SomeNamespace;

void SomeClass :: someMemberFunction()
{
// OK:似乎定义了SomeNamespace :: SomeClass :: someMemberFunction(),
//没有限定它与SomeNamespace ::
}

void someFreeFunction()
{
//不是我们想要的;声明和定义:: someFreeFunction(),而不是
// SomeNamespace :: someFreeFunction()(很容易理解)
}

int main()
{
SomeClass a;
a.someMemberFunction(); // 好;它定义如上。
SomeNamespace :: someFreeFunction(); //未定义!
return 0;所以我的问题是上面的定义SomeClass :: someMemberFunction()的方式。法律,在规范中提到这里?如果合法,是否明智?它一定削减杂乱! :)



非常感谢:)

解决方案

成员函数,编译器意识到它是一个必须属于以前声明的类的成员函数,所以它看起来像在标准9.3.5节中规定的类:


如果成员函数的定义在词法上超出了类
定义,那么成员函数名应该由其类
限定,使用::运算符。 [注意:在成员函数
定义中使用的名称(即在参数声明子句中包括
的默认参数(8.3.6),或在成员函数体中使用,
a构造函数(12.1),在mem初始化表达式
(12.6.2)中)如3.4所述。 ] [示例:

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

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

X 的成员函数 f 在全局范围中定义;
符号 X :: f 指定函数 f 是类 X
X 的范围内。在函数定义中,参数
T 指的是类中声明的typedef成员 T c $ c> X
默认参数计数指的是在 X 中声明的静态数据成员计数
。 ]


基本上,你所做的是很好的。但是,当使用嵌套命名空间或具有长名称(或两者)的命名空间时,还有另一种(最好的)减少混乱的方法 - 定义别名:

  namespace short_name = averylong :: nested :: namespacename; 


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:

Header:

// 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 :)

解决方案

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;

这篇关于定义命名空间成员与自由功能,无需限定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆