在命名空间中的另一个函数内部正向声明命名空间中的一个函数

Forward declaring a function in a namespace inside another function in that namespace

本文关键字:函数 命名空间 一个 另一个 内部 声明      更新时间:2023-10-16

我有两个源文件,a.cppb.cpp。在a.cpp中,我有一个函数,foo:

namespace ns { void foo() { std::cout << "foo!"; } }

b.cpp中,我在名称空间ns中有另一个函数,我想在其中原型并调用foo:

namespace ns
{
void bar()
{
    void foo();
    foo();       
}
}

虽然以上内容在语法上是有效的,但它会导致编译器认为foo在全局命名空间中(或者至少这是我从执行此操作时遇到的链接器错误中推断出的)。我的前两个解决方案是void ns::foo();namespace ns { void foo(); },但都无效。是否有可能在bar中正确地原型化该功能?

请注意,我知道我可以简单地将其移动到文件范围或头文件中,对此有很多问题,但我想在另一个函数中专门对其进行原型化。我的编译器是最新更新的MSVC 14.0。

编辑:根据我所做的一些测试和我们在评论中的讨论,我认为这是一个MSVC错误。比较:

namespace ns
{
void bar()
{
    void foo();   // link error, MSVC assumes global namespace
    foo();
}
void foo() { }
} // namespace ns

如前所述,这是失败的。然而,将原型从函数中移出会使MSVC正确地将原型化的函数放置在封闭的命名空间中:

namespace ns
{
void foo();   // all fine
void bar()
{
    foo();
}
void foo() { }
} // namespace ns

标准对这一点很清楚:

3.3.2/11:(..)块范围内的函数声明和块范围内带有外部说明符的变量声明请参阅作为封闭命名空间的成员的声明(…)

因此:

void bar()
{
    void foo();   // should refer to ns::foo() according to 3.3.2/11
    foo();
}

链接应指具有相同签名的单独编译的函数:

1.3.17签名:<function>名称、参数类型列表和封闭命名空间(如果有)[注意:签名用作名称篡改和链接--尾注]