一、内联命名空间
首先,我们简单回顾下命名空间的作用。在开发一个大型项目过程中,会有很多开发人员参与开发,也会引入很多第三方库,项目代码引用了同名的类和函数无法避免。这个时候使用命名空间来区分不同的类和函数就可以解决冲突的问题。
例如
namespace s
{
namespace v1
{
void print()
{
std::cout << "this is s1 func......" << std::endl;
}
}
namespace v2
{
void print()
{
std::cout << "this is s2 func!!!!!!" << std::endl;
}
}
}
int main()
{
s::s1::print(); //使用了s1中的print函数
s::s2::print(); //使用了s2中的print函数
}
C++11提出了内联命名空间的概念。被声明为内联的命名空间,可以将其所有成员导出到父命名空间。使用一个例子具体说明:
将上述v2改为内联命名空间,即在v2之前添加inline声明即可,其他不用修改
inline namespace v2
这样修改之后,使用v2中成员的时候就可以不用再指定v2命名空间了
s::print(); //使用s1可以不指定s1命名空间
s::v1::print(); //使用s2必须要指定s2命名空间
通常,我们可以在一些第三库的头文件中见到内联命名空间的应用。
如果我们想要对一些接口进行升级,同时保留老接口,因为并不是所有用户都希望升级到新接口。那么就可以将最新版本作为内联命名空间,使“默认”使用新接口。
比如上面的print接口,当从v1升级到v2时,将v2作为内联命名空间。这样就可以让用户用s::print,默认使用了v2新接口,同时用s::v1::print可以继续使用v1版本的老接口。
二、嵌套命名空间和嵌套命名空间的简化语法
其实在上面已经使用了嵌套命名空间。即
namespace s
{
namespace v1
{...}
}
嵌套命名空间可以更加方便我们解决命名冲突的问题。
但是有些时候,嵌套好些命名空间只是为了声明某个类或函数,这时可以使用简化语法写出来。
注意:简化语法在C++17标准才开始支持。
namespace SA::SB::SC
{
int func() {}
}
相当于
namespace SA
{
namespace SB
{
namespace SC
{
int func() {}
}
}
}
在C++20的时候,内联嵌套命名空间也可以进行简化。
namespace SA::SB::inline SC
{
int func() {}
}
相当于
namespace SA
{
namespace SB
{
inline namespace SC
{
int func() {}
}
}
}