从同名未命名命名空间中的函数调用全局函数



我有一些代码。file1.cpp:

extern void callout();
int answer() {
return 5;
}
int main(){
callout();
return 0;
}

file2.cpp

#include <iostream>
using std::cout; using std::endl;
namespace {
int answer() {
cout << ::answer() << endl;
return 12;
}
}
void callout() {
cout << answer() << endl;
}

未命名命名空间中的answer()函数不是调用全局answer()函数,而是递归地调用自己,导致堆栈溢出。如何在未命名的命名空间中从answer()函数调用全局answer()函数?

首先,如果你想调用一个函数,它需要在翻译单元中声明。file1.cpp中的answer函数目前没有在file2.cpp的翻译单元中声明。

要解决这个问题,请在两个.cpp文件中添加包含

的头文件。
int answer();

(顺便说一下:extern在函数声明上几乎是无用的)

这样,限定的调用::answer()应该像您希望的那样工作,调用全局命名空间中的重载。

不幸的是,正如您在评论中指出的那样,它将导致不合格的调用callout中的answer()失败。这是因为未命名的名称空间的行为就像使用了using namespace /* unnamed namespace name */;一样,而非限定名称查找将同时考虑名称空间中的重载以及引入的重载"if"。命名空间的一部分,同样是由using指令引起的。

我认为在这种情况下,没有任何方法可以从未命名的命名空间外部调用answer。您不能通过重载解析来区分函数,也不能通过名称来选择未命名的名称空间中的函数,因为未命名的名称空间没有可以引用的名称。最好的选择是在file2.cpp中重命名answer,或者在未命名的名称空间中添加一个函数,用不同的名称将调用转发到answer。在未命名的名称空间内,一个简单的非限定调用answer()将调用未命名的名称空间中的函数,并且不会考虑全局名称空间作用域。

如果您不使用(仅)未命名的名称空间,那么所有这些都会更容易。如果有一个命名空间来区分这两个函数,那么任何一个函数都可以通过限定名调用。

最新更新