从具有相同名称的未命名命名空间中的函数调用全局函数

Global function call from function in unnamed namespace with the same name

我有一些代码。 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.cppanswer 函数当前未在 file2.cpp 的翻译单元中声明。

要解决此问题,请在包含

.cpp 个文件中添加一个头文件
int answer();

(顺便说一句:extern 在函数声明上几乎没用)

有了这个,合格的 调用 ::answer() 应该可以如您所愿地工作,调用全局命名空间中的重载。

不幸的是,正如您在评论中指出的那样,这将导致 不合格 调用 answer() in callout 失败。这是因为未命名的命名空间的行为就好像使用了 using namespace /* unnamed namespace name */; 并且未限定的名称查找将同时考虑命名空间中的重载以及由于 [=43= 而引入的“好像”部分命名空间的重载]同样。

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

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