使用命名空间来定义全局函数

3
在源文件中定义类成员函数时,我们可以使用 using namespace ns1::ns2::...::nsx 来避免必须完全限定函数名称。
例如:
// Header file - foo.hpp
namespace ns1::ns2 {
    class FooClass {
        void fooMethod();
    }
}

// Source file - foo.cpp
#include "foo.hpp"
using namespace ns1::ns2;
void FooClass::fooMethod() {
    // do something
}

然而,最近我在尝试定义一个全局函数时感到困惑。
请看以下示例。
// Header file - bar.hpp
namespace ns1::ns2{
    void barFunction();  // <-- compile error: undefined reference
}

// Source file - bar.cpp
#include "bar.hpp"
using namespace ns1::ns2;
void barFunction(){
    // do something
}

我原本期望编译器会推断出在bar.hpp中定义的ns1::ns2::barFunctionbar.cpp的定义。但实际上并没有推断出来。(如果我在定义中使用全限定名,一切都正常运作)。这种情况是否符合预期行为,或者说我做错了什么?

3
你所看到的行为是预期的 - 你的理解有误。using namespace ns1::ns2并不会导致后续对barFunction()的定义在命名空间ns1::ns2中。它意味着ns1::ns2中现有的名称成为与barFunction()中使用的名称匹配的候选项。 - Peter
1
你可以同时使用两个或更多的 usingusing namespace foo; using namespace bar;;那么 barFunction() 应该属于哪个命名空间?using namespace <someNamespace> 指令会导致在使用符号时,符号也会在所有已使用的命名空间中查找;并不是将定义放置在已使用的命名空间中。 - max66
1个回答

3

这是预期的行为。

[namespace.udir]

3 using指示符不会向其所在的声明区域添加任何成员。

这意味着在定义barFunction时,全局命名空间中不存在此函数的声明。这使得此函数的定义成为第一个且唯一的声明(在全局命名空间中)。

这是有意设计的,因为使用指示符经常会带来比预期更多的名称。因此,不让它践踏出现在其中的声明性区域是好的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接