《C++ Template. The Complete Guide》笔记之四 Tricky Basics

来源:互联网 发布:淘宝付款后钱在哪里 编辑:程序博客网 时间:2024/05/18 00:13

这里实际要说到的是一些散乱的比较tricky的概念。不想一一列举了,但是有2个点想拿出来说一说。

第一个就是typename,这个关键字用来告诉编译器,后面紧跟的东西是一个类型而不是其他什么东西。假定你有一个Map的类,需要有2个模板参数Key和Value。

有了这个类之后,我们要实现这里的getPair方法。我们按部就班地写出这个函数的实现:

template<class K, class V> Map<K,V>::MapPair Map<K,V>::getPair() 但是编译的时候,

GCC的编译器(我用的是和CodeBlock绑定的gcc 3.4.5,可能比较老了)告诉我们"error: expected constructor, destructor, or type conversion before "Map"|||=== Build finished: 1 errors, 0 warnings ===|"

VS2005的编译器告诉我们"error C2143: syntax error : missing ';' before 'Map<K,V>::getPair'"和“error C4430: missing type specifier - int assumed. Note: C++ does not support default-int”

这里可以看到VS的编译器还是比较靠谱的,能把你往这个typename关键字上指引,但是GCC的有点诡异。这里的解决方案就是把这个函数写成:

template<class K, class V> typename Map<K,V>::MapPair Map<K,V>::getPair()

这里的typename用来表明这里的::MapPair表示的是MapPair是一个类型,而不是Map<K,V>中的一个变量。这样变量其实我们在STL中经常看见。只是没有特别关注罢了,比如说下面的例子:

上面这个就是在STL istream中的一段定义,这里没有typename可能不能通过编译。更甚者,形如typename T::SubType* ptr;这样的语句如果没有加上typename通过了编译,被解析成为T中的变量SubType乘以ptr才是非常恐怖的。

 

还有一个原来以为没有问题的问题。就是文中提到的this->的问题

来看这样一个例子:

这里的特点是派生类的foo函数中调用干了exit()函数。问题是这里有2个函数,一个是全局的exit函数,一个事父类Base中的成员函数,现在这样的调用究竟是调用哪个函数呢?我们在GCC和VS的编译器中都做了尝试。

VS的编译器似乎很进步,一直为了这些模板问题在做改进。这里的输出是“base exit”。如我们所愿。但是在GCC(gcc 3.4.5)里面输出了"global exit"。Again,可以想到的一个潜在的问题就是如果你写一个在Windows Mobile和Symbian上公用的模块,即使在Windows Mobile上可以运行,但是在Symbian上行为表现可能就不一样了。。

所以这里老老实实的用this->exit();或者Base::exit();才是一个稳妥的办法。

这章里面涉及到的还不止这些内容。比如.template的用法其实也有提及。但是如果是浅尝辄止就没有什么特别的意思了。留待下次在具体分析。

 

 

 

原创粉丝点击