C++ 内联命名空间和扩展命名空间
我阅读了关于名称空间定义的部分。N3797第7.3.1条规定: 内联关键字可用于扩展命名空间定义 仅当它以前用于原始命名空间定义时 对于该名称空间 考虑以下代码段:C++ 内联命名空间和扩展命名空间,c++,namespaces,g++,inline,C++,Namespaces,G++,Inline,我阅读了关于名称空间定义的部分。N3797第7.3.1条规定: 内联关键字可用于扩展命名空间定义 仅当它以前用于原始命名空间定义时 对于该名称空间 考虑以下代码段: namespace M { int h; } inline namespace M { int j = 6; } 无论是使用-std=c++11还是不使用该选项,它都编译成功。你能解释一下这种行为吗?这是一个g++bug吗?您对标准的引用是明确的:这是不允许的 使用Clang++我得到了关于这一点的非常明确的错误
namespace M
{
int h;
}
inline namespace M
{
int j = 6;
}
无论是使用
-std=c++11
还是不使用该选项,它都编译成功。你能解释一下这种行为吗?这是一个g++
bug吗?您对标准的引用是明确的:这是不允许的
使用Clang++我得到了关于这一点的非常明确的错误信息:
Test0614-1.cpp:17:18: error: non-inline namespace cannot be reopened as inline
inline namespace M
^
Test0614-1.cpp:12:11: note: previous definition is here
namespace M
^
因此,这肯定是g++中的一个bug。顺便说一下,这里有报道:
编译器接受标准早期版本的内联名称空间,并且至少没有警告,这似乎是一个问题。这在2010年已被报告为错误,应已修复:
这将导致错误“无法将非内联命名空间作为内联命名空间打开”
inline namespace M
{
int h;
}
namespace M
{
int j = 6;
}
您必须使用:
inline namespace M
{
int h;
}
inline namespace M
{
int j = 6;
}
另一方面,您应该得到一个警告,提示您正在将内联命名空间作为非内联命名空间重新打开
inline namespace M
{
int h;
}
namespace M
{
int j = 6;
}
但它根本没有改变我所能说的任何东西,所以我不知道警告为什么会存在,但它存在的事实和::inline
表明并非如此
namespace M
{
inline namespace F {
int h;
}
}
namespace M::F {
int k;
}
给出相同的警告,当使用以下命令时,该警告将被抑制:
namespace M::inline F {
int k;
}
有趣的是,这是非法的:
inline namespace M
{
inline namespace F {
int h;
}
}
inline namespace M::inline F {
int k;
}
您可以使用namespace M::inline F
或namespace M::F
,但在这两种情况下,您都会收到一条警告,即您正在将内联命名空间M作为非内联命名空间打开
可能只是::inline
的存在只是为了抑制该警告,并让程序员从扩展名称空间中意识到它是一个内联名称空间,无需使用范围解析运算符即可访问,而无需检查主名称空间定义,这使代码和意图变得清晰,由于大多数内联命名空间用于版本控制,它们总是嵌套在全局命名空间范围内的非内联命名空间中,因此不需要使用语法inline namespace M::inline F
。以前必须使用namespace M{inline F{int k;}}
而不是namespace M::F
来在扩展名称空间块上明确该意图