内联命名空间和扩展名称空间

时间:2014-06-14 11:59:41

标签: c++ namespaces g++ inline

我阅读了有关命名空间定义的部分。 N3797的第7.3.1条规定:

  

inline关键字可用于extension-namespace-definition   只有先前在原始命名空间定义上使用它   用于该命名空间。

请考虑以下代码段:

namespace M
{
    int h;
}

inline namespace M
{
    int j = 6;
}

使用-std=c++11编译成功并且没有该选项。你能解释一下这种行为吗?它是g++错误吗?

2 个答案:

答案 0 :(得分:5)

对标准的Vour引用是明确的:这是不允许的。

使用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 ++中的一个错误。顺便说一下,它在这里报告:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53402

编译器接受标准的先前版本的内联命名空间并且至少没有警告这一事实似乎是一个问题。这已经在2010年报告为错误,应该已修复:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43824

答案 1 :(得分:0)

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 Fnamespace M::F,但是在两种情况下,您都将收到警告,即将以非嵌入式命名空间打开嵌入式命名空间M。

可能只是存在::inline是为了抑制该警告,并使程序员从扩展名称空间知道,它是一个内联名称空间,无需作用域解析运算符就可以访问它而不必检查它们。主要名称空间定义,这使代码和意图变得清晰,并且由于大多数内联名称空间用于版本控制,因此它们始终嵌套在全局名称空间范围内的非内联名称空间内,因此不需要使用语法inline namespace M::inline F允许的。以前必须使用namespace M {inline F {int k;}}代替namespace M::F才能在扩展名称空间块中明确表示该意图。