星星博客 »  > 

走进C++11(四十六)inline namespace

关注公众号获取更多信息:

 

这篇文章是这个系列的最后一篇。这个系列是我第一次尝试写一个系列的文章。其中发现了很多不足的地方。回首之前的文章,在排版,内容形式等方面都很欠缺。之后我会努力呈现更好的内容。敬请期待。

 

最后的一篇留给了inline namespace。说起inline namespace不得不先说一下namespace, namespace最常用的就是C++标准的std名字空间。名字空间的作用是区别同名的全局成员,例如在两个头文件中声明了同名的函数,如果在其他地方同时包含了两个头文件,编译时就会报错。
 

C++11当中引入了内联名字空间的特性,内联名字控件可以让不同名字空间之间相互访问

 

内联命名空间

 

内联命名空间是在其原初命名空间定义中使用了可选的关键词 inline 的命名空间。

 

许多情况下(列于下方),内联命名空间的成员都被当做如同它们是其外围命名空间的成员一样。这项性质是传递性的:若命名空间 N 包含内联命名空间 M,它又继而包含内联命名空间 O,则 O 的成员能按如同它们是 M 或 N 的成员一样使用。

 

  • 在外围命名空间中,隐含地插入了一条指名内联命名空间的 using 指令(类似于无名命名空间的隐式 using 指令)

  • 实参依赖查找中,当将命名空间添加到关联命名空间集合时,亦添加其内联命名空间,而当添加内联命名空间到关联命名空间列表时,亦添加其外围命名空间。

  • 内联命名空间的每个成员,都能按照如同它是外围命名空间的成员一样,进行部分特化、显式实例化或显式特化。

  • 检验外围命名空间的有限定名字查找,将包含来自其各个内联命名空间的名称,即使同一名称已存在于外围命名空间也是如此。 

 

内联名字控件可以让不同名字空间之间相互访问,但是这样会破坏名字空间的分割性:

 

 

namespace NameA {    inline namespace NameB {                            // 声明为inline        struct Example {};    }
    inline namespace NameC {                            // 声明为inline        template<typename T> class Class {};        Example exC;                                    // 不用打开名字空间NameB也能使用    }}
namespace NameA {    template<> class Class<Example> {};                // 使用内联名字空间还能在不打开名字空间的情况下,进行模板特化(否则会编译失败)}
using namespace NameA;int main(){    Example ex;                                         // 不用打开名字空间NameB也能使用    Class<Example> classEx;    return 0;}

 

那么它有什么用呢?

 

Image

 

 

代码中为每个版本的类库定义了命名空间,同时将最新版本定义为内联命名空间。有了这样的准备之后,假设我们队类库进行了升级, 就可以实现:

 

  1. 使用者代码不受影响,除非使用者自己想改。

  2. 可以自由使用新类库的功能

  3. 如果有需要仍然可以使用原来的类库

 

 

内联命名空间的应用场景相当有限,但是一旦用上了,还是比较神奇的。

相关文章