我有一些代码。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()
将调用未命名的名称空间中的函数,并且不会考虑全局名称空间作用域。
如果您不使用(仅)未命名的名称空间,那么所有这些都会更容易。如果有一个命名空间来区分这两个函数,那么任何一个函数都可以通过限定名调用。