我有两个源文件,a.cpp
和b.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
答案 0 :(得分:4)
关于这一点,标准很清楚:
3.3.2 / 11:(..)块作用域中的函数声明和块作用域中的extern说明符的变量声明参考 声明是封闭命名空间的成员(...)
因此:
void bar()
{
void foo(); // should refer to ns::foo() according to 3.3.2/11
foo();
}
并且链接应该引用具有相同签名的单独编译的函数:
1.3.17签名:
<function>
名称,参数类型列表和封闭命名空间(如果有)[注意:签名用作基础 名称修改和链接.-结束注释]