转发在该命名空间中的另一个函数内声明命名空间中的函数

use*_*520 6 c++ namespaces visual-c++ function-prototypes

我有两个源文件,a.cppb.cpp.在a.cpp,我有一个功能,foo:

namespace ns { void foo() { std::cout << "foo!"; } }
Run Code Online (Sandbox Code Playgroud)

b.cpp,我在命名空间ns中有另一个函数,我想在其中进行原型化和调用foo:

namespace ns
{

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

}
Run Code Online (Sandbox Code Playgroud)

虽然上面的语法有效,但它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
Run Code Online (Sandbox Code Playgroud)

如前所述,这失败了.但是,将原型移出函数会使MSVC正确地将原型函数放在封闭的命名空间中:

namespace ns
{

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

void foo() { }

} // namespace ns
Run Code Online (Sandbox Code Playgroud)

Chr*_*phe 5

标准对这一点说得很清楚:

\n\n
\n

3.3.2/11: (..) 块作用域中的函数声明和块作用域中带有 extern 说明符的变量声明引用作为封闭命名空间成员的\n 声明(...)

\n
\n\n

最后:

\n\n
void bar()\n{\n    void foo();   // should refer to ns::foo() according to 3.3.2/11\n    foo();\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

并且链接应该引用具有相同签名的单独编译的函数:

\n\n
\n

1.3.17 签名: <function>名称、参数类型列表和封闭命名空间(如果有)[注意:签名用作名称修改和链接的基础。\xe2\x80\x94end note ]

\n
\n