每个库会定义大量的全局名字,而这不可避免的会发生冲突,放在全局命名空间中会造成命名空间污染。
而这时候就可以使用命名空间,来给每一个部分的名字加一个前缀来避免冲突。
使用namespace name{}定义命名空间。可以定义于全局或者其他命名空间里,但不能再函数和类的内部。
每一个namespace就代表了一个作用域。
namespace可以被分开来几个部分定义,但只要声明了该namespace,相当于继续在这个namespace里定义,而不是新开一个。这种能够确保我们所需的函数和其他名字只定义一次。
一般在我们定义的namespace里include,因为这相当于将include里所有东西都放进这个namespace中。
对于一个在namespace中声明的成员,只能在namespace中或全局作用域中声明定义它,不能在不相关的作用域中定义它。
模板特例化的声明必须在原命名空间中,在此之后就可以在外面定义它了。
全局命名空间,::variable。
对于嵌套的命名空间,内部的同名会隐藏外部的同名,因为命名空间就是作用域嘛,要访问就必须通过作用域符来限定。
内联命名空间,只能在第一次声明命名空间的时候进行声明,其中的名字可以被外层命名空间直接使用,一般用于版本控制,但是感觉直接using namespace也可以做到相同的事情。
未命名的命名空间,其作用域与该命名空间所在的命名空间一致,但很重要的一点是,它不能跨文件,而例如全局作用域可以通过extern来跨文件访问。
通过namespace name1=name2可以为非常长的命名空间声明别名。
using声明,一次引入一个命名空间的成员,using namespace::name;可以用于全局作用域,局部作用域,命名空间作用域及类作用域中,但在类作用域中时只能指向基类成员。相当于在声明的地方声明了这个名字,当引入的是一个函数时,会引入这个函数的所有重载版本。
using指示,一次引入一整个命名空间,using namespace name;可用于全局、局部和命名空间作用域中。相当于在声明处所在的命名空间前声明了所有名字。
因此using指示可能会造成二义性,并且只有在使用这个二义性的名字的时候才会报错,因此尽量少用。
//相当于name1所有的名字在这里
fun{
using namespace name1;
//相当于name2在这里。
using namespace::name2;
}