gpt4 book ai didi

c++ - 嵌套在函数中的函数声明的命名空间

转载 作者:行者123 更新时间:2023-12-01 14:57:03 27 4
gpt4 key购买 nike

出于奇怪的原因,我想在函数作用域内声明一个函数。
所以我得到以下代码:

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

在另一个编译单元中,我想定义 bar。
根据我使用的编译器,我需要将 bar 放在命名空间 NS 或全局命名空间中才能链接:

在 clang 中:
namespace NS
{
void bar() {}
}

在 MSVC 上:
void bar() {}

如果有的话,什么是好的行为?

作为一个附带问题,为什么以下代码都没有编译(在我的 2 个编译器上):
namespace NS
{
void foo()
{
void bar();
::bar(); // bar declared in global namespace
}
}

或者
namespace NS
{
void foo()
{
void bar();
::NS::bar(); // bar declared in NS namespace
}
}

谢谢您的帮助。

吉赛贝

最佳答案

Note: Long story, short; msvc is doing it wrong, and clang is correct. This post will explain why by showing relevant snippets, and having standard quotations to back up the claims.



关于第一个片段/问题

介绍

块作用域中的函数声明被称为引用最内部封闭命名空间中的实体,因此在下面的栏中是指 NS::bar。
namespace NS {
void foo () {
void bar (); // (A), forward-declaration of `NS::bar`

bar (); // call (A)
}
}

这意味着您在定义 bar 时必须在命名空间 N 中这样做,或者使用限定 ID 来引用所述实体。

void f ():     // some other `void f()`;  _not_ (A)

void NS::f (); // same `f` as being declared at (A)

namespace NS {
void f (); // same `f` as being declared at (A)
}

标准怎么说? ( n3337 )

3.5p6 Program and linkage [basic.link]

The name of a function declared in block scope and the name of a variale declared by a block scope extern declaration have linkage. If there is a visible declaration of an enity with linkage having the same name and type, ignoring entities declared outside the innermost enclosing namespace scope, the block scope declaration declares the same entitiy and receives the linkage of the previous declaration. If there is more than one such matching entity, the program is ill-formed. Otherwise, if no matching entity is found, the block scope entity receives external linkage.




结论
msvc做错了, clang 显示的行为是正确的。



关于第二个片段/问题

解释

当遇到块范围声明时,它指的是最近的封闭命名空间中的实体,但它确实是 不是 在该命名空间中引入这样的名称。

3.5p7 Program and linkage [basic.link]

When a block scope declaration of an entity with linkage is not found to refer to some other declaration, then that entity is a member of the innermost enclosing namespace. However such a declaration does not introduce the member name in its namespace scope.



请参阅以下示例:
namespace NS {
void foo() {
void bar(); // (A), forward-declaration of `NS::bar`
::NS::bar(); // ill-formed, there is no `::NS::bar` yet
bar (); // legal, call the `bar` being forward-declared by (A)
}
}

上面的(A)指的是即将发布的 ::NS::bar ,但由于前向声明不会使命名空间 NS 具有名为 bar 的实体,因此我们只能引用名为 ::NS::bar 的实体。通过酒吧。
void bar ();    // (A), `::bar`

namespace NS {
void foo() {
void bar(); // (B), forward-declaration of `NS::bar`

::bar(); // call (A)
bar (); // call (B), `NS::bar`

::NS::bar (); // ill-formed, `namespace NS` doesn't have an entity named bar (yet)
}

void bar (); // (C), make `NS` have an entity named bar, this is the one
// being referred to by (B)

void baz () {
::NS::bar (); // legal, `namespace NS` now have an entity named `bar`, as being
// declared in (C)
}
}

关于c++ - 嵌套在函数中的函数声明的命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63682574/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com