【发布时间】:2021-05-20 07:03:03
【问题描述】:
“using”关键字在定义成员函数和非成员函数的上下文中是否有不同的效果?下面的示例代码向我表明它可能。
main.cpp
#include "baz.h"
int main()
{
foo::bar x;
x.baz();
foo::foo_non_member();
}
baz.h
namespace foo
{
class bar
{
public:
bar() = default;
void baz();
};
void foo_non_member();
};
baz.cpp
#include "baz.h"
#include<iostream>
using namespace foo;
void bar::baz()
{
std::cout << "baz\n";
}
namespace foo
{
void foo_non_member()
{
std::cout << "non-member\n";
}
}
以上代码编译运行。
$> g++ main.cpp baz.cpp; ./a.out
baz
non-member
如果我从 baz.cpp 中删除 using namespace foo;,我会收到编译器错误。
$> g++ main.cpp baz.cpp
baz.cpp:5:6: error: ‘bar’ has not been declared
void bar::baz()
如果我放回 using 语句并将 foo_non_member() 的定义移到 foo 命名空间之外,我会收到链接器错误。
$> g++ main.cpp baz.cpp
/tmp/ccHeSwsZ.o: In function `main':
main.cpp:(.text+0x24): undefined reference to `foo::foo_non_member()'
collect2: error: ld returned 1 exit status
为什么using 关键字在这里似乎对bar::baz() 和foo_non_member() 没有相同的效果?
【问题讨论】:
-
它对
namespace foo中声明的每个名称具有完全相同的效果。你在哪里看到不同的效果?你期望什么而不是你得到的结果? -
当
foo_non_member()在显式命名空间块之外定义时,我得到一个链接器错误。当bar::baz()在显式命名空间块之外定义时,我没有收到链接器错误。 -
当一个名字被使用时,它会在一个或多个命名空间中查找。声明或定义名称时,不会在任何地方查找它,而是将其引入到声明它的名称空间中。使用
bar,未定义或声明,因此需要查找它。foo_non_member正在被定义,所以它没有被查找,它被定义在它所在的位置。 -
"那是因为它显然没有进入链接器阶段。"是的,它确实。如果我将它留在显式命名空间块之外并留在
using语句中,它会编译、链接并运行。 -
很抱歉变种太多,无论使用或不使用,在命名空间块内或外。哪一个令人惊讶?
标签: c++ namespaces using