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

时间:2011-08-24 09:59:50

标签: c++ namespaces

我有时在嵌套命名空间中声明类,当涉及到定义它们的成员函数时,我宁愿不必使用这些嵌套的命名空间名称限定每一个,特别是如果它们是长期的。

在定义成员函数之前添加“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()合法,并且在规范中提到了哪些?如果合法,是否可取?它肯定减少了杂乱! :)

非常感谢:)

2 个答案:

答案 0 :(得分:2)

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

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

    void someFreeFunction();
};

您也可以简单地写:

#include "example.h"

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

    void someFreeFunction()
    {
    }
}

答案 1 :(得分:0)

当你定义一个成员函数时,编译器意识到它是一个必须属于先前声明的类的成员函数,所以它看起来是类,如标准9.3.5节所述:

  

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

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

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

f的成员函数X在全局范围内定义;该   表示法X::f指定函数f是类X的成员   在班级X的范围内。在函数定义中,参数   type T是指在类T中声明的typedef成员X   default argument count指静态数据成员计数   在班级X中宣布。 ]

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

namespace short_name = averylong::nested::namespacename;