当包围的命名空间是内联的时候,嵌套的命名空间定义。

问题描述 投票:0回答:1

请考虑以下示范程序

#include <iostream>

inline namespace A
{
}

namespace A:: inline B
{
    void f() { std::cout << "Hello nested namespace definition.\n"; }
}

int main() 
{
    f();

    return 0;
}

编译器对程序的编译结果。clang HEAD 11.0.0 是以下内容

prog.cc:7:11: warning: inline namespace reopened as a non-inline namespace
namespace A:: inline B
          ^
inline 
prog.cc:3:18: note: previous definition is here
inline namespace A
                 ^
1 warning generated.
Hello nested namespace definition.

但根据嵌套的命名空间定义的语法,我不能使用关键词 inline 命名空间A之前。

那么这是编译器的bug还是我做错了什么?

对了,编译器 gcc HEAD 10.0.1 20200 编译程序时没有任何警告。

c++ namespaces definition c++20 inline-namespaces
1个回答
1
投票

clang的fixit-hint是误导性的(因为你实际上不能做它告诉你要做的事情),但程序是好的(虽然是误导性的,因为它看起来像你在声明一个非内联的命名空间,但实际上不是--所以警告并不是完全不合理的)。


暂时不考虑嵌套的命名空间,这其实是没有问题的。

inline namespace N { int i=0; };
namespace N { int j=1; };
int k=j;

我们唯一的规则是,从 [namespace.def]3是(重点是我)。

inline 关键字可以用在 命名空间定义 命名空间的 唯有 它曾被用在 命名空间定义 最初宣布的 命名空间名 的命名空间。

措辞是 "只有当",而不是 "如果且只有当"--所以您不能将一个命名空间标记为 inline 但如果一个命名空间的第一个声明为 inline但不是每一个后续的声明都必须如此。

正如OP中所指出的,反正clang在这上面是有警告的。因为这有点误导人。


但为什么我们不能在前面贴上一个引导性的 "声明 "呢?inline 在那里?

如上所述 本报嵌套命名空间的问题,允许使用 领先 命名空间 inline 是会导致程序员产生歧义。

inline namespace std::experimental::parallelism_v2;  // not immediately to reader,
                                                     // is std or parallelism_v2 inline?

如果你统一了领导层,也会有同样的情况。inline 与嵌套 inline 把它放在 namespace:

namespace inline std::experimental::parallelism_v2;  // immediately to reader?
                                                     // std or parallelism_v2 inline?

所以这意味着不支持。如果你想用顶层的名字空间来嵌套一个名字空间 inline...你不能。顶级命名空间必须是非inline (我想我们可以考虑像这样的语法,如 namespace ::inline N::inline M 但这只是奇怪的方式)。)


© www.soinside.com 2019 - 2024. All rights reserved.