封闭命名空间内联时的嵌套命名空间定义

Posted

技术标签:

【中文标题】封闭命名空间内联时的嵌套命名空间定义【英文标题】:Nested namespace definition when the enclosing namespace is inline 【发布时间】:2020-08-07 06:17:30 【问题描述】:

考虑以下演示程序

#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.

但是根据嵌套命名空间定义的语法,我可能不会在命名空间A之前使用关键字inline

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

顺便说一句,编译器gcc HEAD 10.0.1 20200 编译程序时没有任何警告。

【问题讨论】:

我真的不明白为什么你 DV 我的答案,probem 不是取消引用部分,这实际上是正确的,最初我也这么认为,问题是 for 循环限制是另一种方式大约。实际上,我很欣赏您的回答并多次对其进行紫外线照射。 【参考方案1】:

clang 的 fixit-hint 具有误导性(因为您实际上无法执行它告诉您做的事情),但程序很好(尽管具有误导性,因为看起来您在声明非内联命名空间时你真的不是 - 所以警告并非完全不合理)。


暂时忽略嵌套的命名空间,这实际上很好:

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

[namespace.def]/3 的唯一规则是(强调我的):

inline 关键字可用于扩展命名空间的命名空间定义仅当它以前用于命名空间定义 em> 最初为该命名空间声明了 namespace-name

措辞是“仅当”,而不是“当且仅当”-因此您不能标记以前未标记的命名空间 inline...但如果命名空间的第一个声明是 inline ,并非所有后续声明都必须如此。

正如 OP 中所述,无论如何,clang 都会对此发出警告。因为这有点误导。


但是为什么我们不能在里面放一个领先的inline

如the paper 中所述,允许嵌套命名空间与leading 命名空间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 这样的语法,但这本身就很奇怪)。


【讨论】:

但在 C++ 20 标准中并没有说这个定义是错误的。 @VladfromMoscow 重新排序了答案,因此更清楚我并不是说定义不正确。

以上是关于封闭命名空间内联时的嵌套命名空间定义的主要内容,如果未能解决你的问题,请参考以下文章

为啥内联未命名的命名空间?

寻求对内联命名空间的澄清

命名空间

非内联命名空间不能作为内联重新打开

C++入门(命名空间缺省参数函数重载引用内联函数)

C++入门语法第一篇:(命名空间缺省参数函数重载引用内联函数)