《深入理解C++11》笔记-内联名字空间

上一篇:《深入理解C++11》笔记-用户自定义字面量
名字空间或者是命名空间,大家应该都有所了解,最常用的就是C++标准的std名字空间。名字空间的作用是区别同名的全局成员,例如在两个头文件中声明了同名的函数,如果在其他地方同时包含了两个头文件,编译时就会报错。

// test1.h
void func();
// test1.cpp
void func(){}

// test2.h
void func();
// test2.cpp
void func(){}

而通过名字空间可以解决这个问题:

// test1.h
namespace A{
void func();
}
// test1.cpp
namespace A{
void func(){}
}

// test2.h
namespace A{
void func();
}
// test2.cpp
namespace A{
void func(){}
}

这样就能区分两个版本的同名函数,不过在使用的时候需要通过A::func()或者B::func()来调用,或者在使用前通过using A获取中using B打开名字空间然后直接调用函数。
名字空间能够有效分割不同的功能或模块,但是也会引起一些问题。例如名字空间的嵌套使用,在名字空间外部需要声明多个名字空间。

namespace NameA {
    namespace NameB {
        struct Example {};
    }

    namespace NameC {
        Example ex;                  // 无法通过编译
        NameB::Example ex;           // 加上名字空间后能够编译通过
    }
}

int main()
{
    NameA::NameB::Example ex;
    return 0;
}

或者在NameA中通过using打开名字空间,这样外部调用只需要知道NameA名字空间。

namespace NameA {
    namespace NameB {
        struct Example {};
    }

    namespace NameC {
    }

    using namespace NameB;
}

int main()
{
    NameA::Example ex;
    return 0;
}

C++11当中引入了内联名字空间的特性,内联名字控件可以让不同名字空间之间相互访问,但是这样会破坏名字空间的分割性:

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;
}

这种用法通常用来实现根据编译器支持的C++版本调用不同代码:

namespace NameA {
#if __cplusplus == 201103L
    inline
#endif //  __cplusplus
    namespace cpp11 {
        struct Example {};
    }

#if __cplusplus < 201103L
    inline
#endif //  __cplusplus
    namespace cppold {
        struct Example {};
    }
}

using namespace NameA;
int main()
{
    Example ex;                     // 根据编译器的C++版本默认选择inline版本
    cppold::Example ex;
    cpp11::Example ex;
    return 0;
}

下一篇:《深入理解C++11》笔记-模板的别名、模板的SFINEA规则

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值