请考虑以下示范程序
#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
编译程序时没有任何警告。
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
但这只是奇怪的方式)。)