C++ 匿名namespace的作用以及它与static的区别

来源:互联网 发布:女神异闻录5音乐 知乎 编辑:程序博客网 时间:2024/06/05 02:06

假如我们有一个全局对象或者函数只希望它在一个tu中有效,又希望能够用它的地址来实例化一个模板,怎么办?只在一个tu中有效,可以选择internal linkage,但是要用它的地址做为模板参数,又要求它必须要是external linkage!!
很显然,匿名namespace不改变其内部标识符的linkage这一性质解决了这一难题,我们可以把这个全局对象或者函数放心的扔在一个匿名namespace中,然后用它的地址来实例化一个模板,绝对不会发生重定义错误:)

现在大部分C++书籍都认为匿名namespace和static是相同的,而正如这里所阐述的,它们之间差异是明显的:static修饰的标识符由于internal linkage的限制,是不能用来实例化模板的!

最后给出一个例子证实匿名namespace确实不改变linkage,呵呵
代码中验证了external linkage/internal linkage/no linkage三种情况
-------------------------------------------------------------------------------

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
template <char *p>
struct foo
{
    void bar(){puts("bar");
};
static char a ='a';
namespace
{
    char b = 'b';
    static char c = 'c';
    template <class T> struct xxx {};
    void foobar()
    {
        struct no_linkage {};
        xxx<no_linkage>();  // 如果编译错误,说明no_linkage的linkage没有变化
    }
}
int main()
{
    foo<&a>().bar();  // 由于a的linkage是internal,因此应该编译错误
    foo<&b>().bar();  // 如果编译正确,说明b的linkage是external
    foo<&c>().bar();  // 如果编译错误,说明c的linkage是internal
    foobar();
    return 0;
}

-------------------

0 0