c++ - 封闭命名空间内联时的嵌套命名空间定义
问题描述
考虑以下演示程序
#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 之前使用关键字。
那么这是编译器的错误还是我做错了什么?
顺便说一句,编译器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
,但这只是以它自己的方式很奇怪)。
推荐阅读
- c# - 从表单 F1 打开表单 F2,然后卸载表单 F1
- android - 带有跟我来的谷歌地图
- javascript - 如何从 JS-Function 写入 ViewData
- python - TimeseriesGenerator feed 和 Dense 层的不兼容形状 - Keras/Tensorflow
- windows - 使用 powershell 在 IIS 10 中重新绑定证书
- java - Hibernate、Spring 框架和多对多
- java - 在 Spring 上下文初始化期间使用 PowerMock
- flutter - 无法在颤动的 TextFormField 中添加 GIF
- java - JPQL,是否可以使我选择的对象的子集合不同?
- javascript - 每次为动态创建的表获取更新的列数