定义命名空间成员与无限定的自由函数

发布于 2024-12-01 07:08:12 字数 1166 浏览 2 评论 0原文

我有时在嵌套命名空间中声明类,当涉及到定义它们的成员函数时,我不喜欢用这些嵌套命名空间名称来限定每个类,特别是如果它们很长的话。

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

作为我的意思的一个例子:

标题:

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

    void someFreeFunction();
};

实现:

// 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;
}

所以我的问题:上面定义 SomeClass::someMemberFunction() 的方法是否合法,规范中的哪里提到了这一点?如果合法的话,是否值得推荐?它确实减少了混乱! :)

非常感谢:)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猛虎独行 2024-12-08 07:08:12

也许我弄错了,但如果你有:

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

    void someFreeFunction();
};

你也可以简单地写:

#include "example.h"

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

    void someFreeFunction()
    {
    }
}

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()
    {
    }
}
千纸鹤 2024-12-08 07:08:12

当您定义成员函数时,编译器意识到它是一个必须属于先前声明的类的成员函数,因此它会向上查找该类,如标准第 9.3.5 节中所指定的:

如果成员函数的定义在词法上位于其类之外
定义时,成员函数名称应由其类限定
使用 :: 运算符命名。 [注:成员函数中使用的名称
定义(即在参数声明子句中包括
默认参数(8.3.6),或者在成员函数体中,或者,对于
构造函数 (12.1),位于 mem-initializer 表达式中
(12.6.2)) 按照 3.4 中的描述进行查找。 ] [示例:

<前><代码>结构X {
typedef int T;
静态T计数;
无效 f(T);
};

void X::f(T t = 计数) { }

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

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

namespace short_name = averylong::nested::namespacename;

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文