【发布时间】:2016-01-01 20:20:44
【问题描述】:
我有两个源文件,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。
编辑:根据我所做的一些测试以及我们在 cmets 中的讨论,我相信这是一个 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
【问题讨论】:
-
@JoachimPileborg 在函数内部无效。 cpp.sh/3g3hu
-
以下编译运行良好;这不是你想要的吗? gist.github.com/jncornett/8e4d85e6008087438cf5
-
@JoelCornett 它编译得很好,但没有链接,至少不适合我(MSVC 14.0)。
-
@szczurcio 看起来像一个 MSVC 错误。在 gcc 和 clang 上尝试过,它可以工作(Joel Cornett 的 gist.github.com/jncornett/8e4d85e6008087438cf5)
-
标准非常明确:“当一个具有链接的实体的块范围声明未找到引用其他声明时,则该实体是最内层封闭命名空间的成员。但是,这样的声明不会在其命名空间范围内引入成员名称。” [basic.link]p7
标签: c++ visual-c++ namespaces function-prototypes