有关C++命名空间的概念,已经写过一篇了,但是这一块感觉有很多可以说的东西,想起啥就说点啥吧,昨天我们说的那篇文章的开头就说了using namespace std的例子,为什么写了这个语句之后,我们写cout等东西就不需要写命名空间的作用范围了,比如std::cout变成cout,是因为当我们使用using声明的时候,相当于说告诉当前的cpp文件,接下来的作用域范围内,std这个namespace已经属于你了,而我们会遇到比较长的namespace的名字,比如昨天的:
namespace namespace_1 { void func() { std::cout << "namespace_1" << std::endl; } }
这种情况下,我们为了偷懒,可以直接在main函数里面写上我们将要用的namespace的名字,比如:
using namespace namespace_1; int main(){ func();//call namespace_1::func() //namespace_2::func(); //func();// func is undefined }
这当然是没什么问题,但是接下来如果我们是把namespace_2也如此声明,并且两者里面都定义了名叫func的函数,那么会怎样呢?
using namespace namespace_1; using namespace namespace_2; int main(){ func();//call namespace_1::func() //func();// func is undefined }
我们可以看到这里产生了二义性,编译器不知道该去调用哪一个func了
这种情况下我们应该怎么办呢,我们可以考虑使用using来指定我们需要使用的操作:
using namespace namespace_1; using namespace namespace_2; int main(){ using namespace_2::func; func();//call namespace_2::func() //func();// func is undefined }
这种using的用法就是告诉编译器,下面用到的func都来自我的namespace_1的命名空间。我一般是不会去这样操作的,我会直接使用namespace本身的名字去指定想要调用的函数,这样也增加了别人读你代码的可读性,这里只是分享一下可以使用的处理办法。
内联命名空间
内联命名空间这个东西是C++11的新标准,属于嵌套命名空间,可以直接使用外层的命名空间进行访问内部的成员或者function,还是举个例子来看:
/*test_namespace_1.hpp*/ #pragma once #include<iostream> namespace namespace_1 { inline namespace ns_1 { void func_inline() { std::cout << "ns_1" << std::endl; } } namespace ns_2 { void func() { std::cout << "ns_2" << std::endl; } } }
我们可以看到在这个hpp中,我将ns_1最前面加了inline关键字,这就是告诉编译器,我这个命名空间是内联的,而下面的ns_2就没有这个关键字,我们来看一下main函数的调用情况:
int main(){ namespace_1::func_inline(); namespace_1::ns_2::func(); namespace_1::func();//namespace_1 has no member func() //func();// func is undefined }
直接调用namespace_1下的func_inline是没问题的,因为这是内联中一个成员函数,但是如果直接调用func那就是会报错了。