我阅读了关于命名空间定义的部分。N3797的第7.3.1条款中说:
inline关键字只能用于扩展命名空间定义中,前提是它之前已经用于该命名空间的原始定义。
考虑以下代码片段:
namespace M
{
int h;
}
inline namespace M
{
int j = 6;
}
使用-std=c++11
选项和不使用该选项都可以成功编译。你能解释一下这种行为吗?这是一个g++
的bug吗?
我阅读了关于命名空间定义的部分。N3797的第7.3.1条款中说:
inline关键字只能用于扩展命名空间定义中,前提是它之前已经用于该命名空间的原始定义。
考虑以下代码片段:
namespace M
{
int h;
}
inline namespace M
{
int j = 6;
}
使用-std=c++11
选项和不使用该选项都可以成功编译。你能解释一下这种行为吗?这是一个g++
的bug吗?
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。顺便提一下,这里有报告:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53402
编译器接受之前版本的内联命名空间而没有至少发出警告的事实似乎是一个问题。这在2010年已经被报告为错误并应该得到修复:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43824
namespace M
{
int h;
}
inline 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
,以在扩展命名空间块上明确该意图。