寻求对内联命名空间的澄清

Posted

技术标签:

【中文标题】寻求对内联命名空间的澄清【英文标题】:Seeking clarification on inline namespace 【发布时间】:2018-10-10 02:07:19 【问题描述】:

在cppreference中,找到以下文字:

内联命名空间的每个成员都可以部分特化, 显式实例化或显式特化,就好像它是 封闭命名空间的成员。

注意:关于专业化的规则允许库版本控制: 库模板的不同实现可以定义在 不同的内联命名空间,同时仍然允许用户扩展 具有显式特化主名称空间的父名称空间 模板。

这些陈述意味着什么?谁能通过一个简单的例子来解释一下?

【问题讨论】:

【参考方案1】:

考虑一个愚蠢的例子:

#include <iostream>

namespace foo 
    inline namespace v1 
        template <typename T>
        void bar(T t) 
            (void) t;
            std::cout << "Generic bar\n";
        
    

    template <>
    void bar<int>(int v) 
        (void) v;
        std::cout << "Specialized bar\n";
    


int main() 
    foo::bar(12);
    foo::v1::bar(12);
    foo::bar(12.0);
    return 0;

如果你运行它,你会得到以下输出:

Specialized bar
Specialized bar
Generic bar

这是因为使用int 调用foo::bar 是专门针对foo 的,尽管foo::v1 中存在默认实现。

这个例子没用,但考虑一个场景,你想在外部库(包括 stl)中专门化 template 函数或 class。你不知道vectorstd 还是std::cxx11 的成员(libc++ 在很多事情上都使用std::__1)。由于inline namespace 是一种在API 级别提供版本控制的方法(例如,您将inline namespace 更改为v2 并单独保留v1),这让最终用户可以在不知道@987654337 详细信息的情况下进行专业化@d namespaces.

【讨论】:

以上是关于寻求对内联命名空间的澄清的主要内容,如果未能解决你的问题,请参考以下文章

在命名空间中转发声明类

Jaxb:在同一个包中解组具有多个命名空间的 xml

使用javascript重命名输入中的文本(每点更改空间)

Linux - 了解挂载命名空间和克隆 CLONE_NEWNS 标志

命名空间

C# 常用 命名空间都有哪些 这些命名空间是的作用是?