1、问题起因(使用boost.asio库时为什么如下图所示using后面不接namespace)
图上的using boost::asio::ip::tcp 在using后面没有namespace,这样是正确的。那么如果加上namespace会是什么结果呢?
加上之后如上图所示,出错。为什么?在之前我也一直不能明白原因,查了using的用法但也没有弄清楚。
其实答案很简单:因为boost::asio::ip 是namespace,而tcp不是,他应该是一个类。
1 namespace boost{ 2 namespace asio{ 3 namespace ip{ 4 class tcp{ 5 ... 6 } 7 ... 8 } 9 .... 10 } 11 ..... 12 }
如上面代码所示,我们就可以写using boost::asio::ip::tcp了,这是using了一个命令空间中的tcp类的作用域。
这个问题算是解决了。
2、问题又来了(为什么可以如下图使用)
acceptor是一个(类类型)class_type,然后他又在tcp这个作用域下面,而tcp它是一个类,为什么在这个类中还有类型,其实就是boost::asio::ip::tcp::acceptor (本人的知识在这不够用了,感觉卡在这了)
这个问题的回答是这样的,如下面代码,代码中有类A,类A中有个类型是iterator类型,这是一个typedef,因此当你使用iterator时,就需要加入A::iterator这样,上图tcp就是那个类,acceptor(应该)就是那个typedef,这样就解释清楚了。
1 class A_iterator ; 2 class A { 3 public: 4 A(){std::cout << " A is start \n";} 5 ~A(){std::cout << "A is finst \n";} 6 typedef A_iterator iterator; 7 }; 8 class test ; 9 class A_iterator { 10 public: 11 A_iterator(){std::cout << "A_iterator is start \n";} 12 ~A_iterator(){std::cout << "A_iterator is finsh \n";} 13 typedef test test_type ; 14 }; iterator it //错误 A::iterator it1 //正确
3、将两个问题连在一起测试
1 #include<iostream> 2 namespace my{ 3 4 class A_iterator ; 5 class A { 6 public: 7 A(){std::cout << " A is start \n";} 8 ~A(){std::cout << "A is finst \n";} 9 typedef A_iterator iterator; //我们使用iterator去定义对象,而一般不使用A_iterator 去定义对象 10 }; 11 12 class test ; 13 class A_iterator { 14 public: 15 A_iterator(){std::cout << "A_iterator is start \n";} 16 ~A_iterator(){std::cout << "A_iterator is finsh \n";} 17 typedef test test_type ; //我们使用test_type去定义对象,而一般不使用test去定义对象 18 }; 19 20 class test { 21 public : 22 test(){std::cout << "test is start \n";} 23 ~test(){std::cout << "test is finst \n";} 24 }; 25 26 } 27 int main() 28 { 29 my::A::iterator it ; //没有问题,作用域限定全 30 //my::iterator it2; //有问题,my下面没有iterator ,应该在my::A 下面 31 my::A::iterator::test_type t1 ; //没有问题,my命令空间中有iterator,iterator下面有test_type 32 //using namespace my //没有问题,因为my命名空间所有东西都引入进来。 33 using my::A; //没有问题,my是命名空间,A是类,只引入A类中的东西 34 //using my::A::iterator; //有问题,A是类,不是命名空间不能使用。(注意:倒数第二个作用域后面一定要是命名空间) 35 A::iterator tt2; //没有问题 36 A::iterator::test_type tt3; //没有问题 37 //iterator::test_type t2 ; 38 return 0; 39 }
1 #include<iostream> 2 class B; 3 class A { 4 public: 5 typedef B b; 6 }; 7 8 class B{ 9 public: 10 }; 11 12 int main() 13 { 14 using ::A ; 15 A::b ins ; 16 //b ins2 ; //有问题,需要类名限定 17 return 0; 18 }
4、总结:
①using A::B::C::D 时,D之前必须为命名空间。
D如果是个类就可以用D::something使用,使用something必须加D::。
②using namespace A::B::C::D 时,D也要为命名空间。
D里面所有东西都引入了,可以使用命名空间,不加D::作用域
③在这就不难解释std::vector<int>::iterator it
std是命名空间,vector<>类模板,iterator是vector<>中的一个typedef
④类里面是一个作用域,但类不是命名空间。所以类可以被放在using最后一个命令空间的作用域下面(同时它也必须在一个命名空间下面)才能被using。
⑤using std::cout ; 这里应该是引入一个对象,在std命令空间里面有个cout(对象)。有点迷惑了。