Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 内联命名空间和扩展命名空间_C++_Namespaces_G++_Inline - Fatal编程技术网

C++ 内联命名空间和扩展命名空间

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++我得到了关于这一点的非常明确的错误

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

内联关键字可用于扩展命名空间定义 仅当它以前用于原始命名空间定义时 对于该名称空间

考虑以下代码段:

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
来在扩展名称空间块上明确该意图