在该命名空间中的另一个函数内向前声明一个命名空间中的函数 [英] Forward declaring a function in a namespace inside another function in that namespace

查看:89
本文介绍了在该命名空间中的另一个函数内向前声明一个命名空间中的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two source files, a.cpp and b.cpp. In a.cpp, I have a function, foo:

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

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

In b.cpp, I have another function in namespace ns in which I'd like to prototype and call foo:

namespace ns
{

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

}

虽然以上在语法上是有效的,但它导致编译器认为 foo 在全局命名空间中(或者至少这是我从我这样做时得到的链接器错误中推断出来的)).我首先要解决的两个想法是 void ns::foo();namespace ns { void foo();},但两者都无效.是否可以在 bar 中正确地创建此函数的原型?

While the above is syntactically valid, it leads the compiler to think that foo is in the global namespace (or at least that's what I've deduced from the linker errors I get when I do this). My first two ideas to fix that were void ns::foo(); and namespace ns { void foo(); }, but neither is valid. Is it possible to correctly prototype this function inside bar?

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

Note that I know I could simply move this to the file scope or a header file, there have been many questions asked about this, but I want to specifically prototype it inside another function. My compiler is MSVC 14.0 with the latest update.

根据我所做的一些测试以及我们在评论中的讨论,我相信这是一个 MSVC 错误.比较:

Based on some tests I've done and our discussion in the comments, I believe this is an MSVC bug. Compare:

namespace ns
{

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

void foo() { }

} // namespace ns

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

This fails, as stated previously. However, moving the prototype out of the function makes MSVC correctly place the prototyped function in the enclosing namespace:

namespace ns
{

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

void foo() { }

} // namespace ns

推荐答案

标准明确了这一点:

3.3.2/11: (..) 块范围内的函数声明和块范围内带有 extern 说明符的变量声明参考封闭命名空间的成员 (...)

3.3.2/11: (..) Function declarations at block scope and variable declarations with the extern specifier at block scope refer to declarations that are members of an enclosing namespace (...)

因此:

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

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

and the linking should refer to the separately compiled function which has the same signature:

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

1.3.17 signature: <function> name, parameter type list , and enclosing namespace (if any) [Note: Signatures are used as a basis for name mangling and linking.—end note ]

这篇关于在该命名空间中的另一个函数内向前声明一个命名空间中的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆