当使用命名空间指令时,为什么函数前面没有附加命名空间前缀?

9
这个C++文件...
namespace foo {
    class C {
        void m();
    };
    void f();
}

using namespace foo;

void C::m() {}
void f() {}

编译成一个带有以下符号的目标文件:

$ g++ foo.cpp  -c
$ nm foo.o  -C
000000000000000a T f()
0000000000000000 T foo::C::m()

为什么C::m()会添加命名空间前缀,但f()不会呢?
(如果我使用namespace foo {...}而不是using namespace foo,那么两个名称都会添加foo前缀。)

正如答案所示,编写问题时不要贸然下结论。如果有什么令人惊讶的地方,最好小心地对待这种看似矛盾的情况,并询问类似“链接是否不同?”的问题,而不是假设它确实如此(因为实际上链接与您的情况无关;所有涉及的链接都是外部链接)。 - Kerrek SB
1
@KerrekSB,我更新了标题,不再对原因进行假设。(在处理C++时,我经常混淆链接、作用域和存储分配)。 - Daniel Näslund
1个回答

13
void C::m() {} 中,C::m 是限定名称,这样的定义总是指向先前声明的某个内容。编译器查找 C,发现 C 实际上是 foo::C,感谢 using-directive,并将 void C::m(){} 视为 foo::C::m() 的定义。
当你写 void f() {} 时,这是未限定名称,它始终在当前命名空间(全局命名空间)中声明该函数。

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