C++的杂七杂八:模板的右尖括号(>)

/ 0评 / 0

Published by orzz.org(). (http://orzz.org/template-specializations-in-cxx11/)

在C++98/03的泛型编程中,模板实例化有个很恼人的地方。那就是连续的两个右尖括号(>>)会被编译器解释成右移操作符,而不是模板参数表的结束。

让我们来看看下面这个例子:


使用gcc编译时,我们会得到如下错误提示:

意思就是,“Foo>”这种写法是不被支持的,让我们写成这样:“Foo>”(注意两个右尖括号之间的空格)。

这种限制无疑是很没有必要的。在C++的各种成对括号中,目前只有右尖括号连续写两个会出现这种二义性。让我们想象一下,static_cast、reinterpret_cast等C++标准转换运算符,可也都是使用“<>”来获得待转换类型(type-id)的。若这个type-id本身是一个模板,用起来多么的不方便!

现在在C++11中,这种限制终于被取消了。

参考《ISO/IEC 14882:2011》,14.2 Names of template specializations,第3款:

“When parsing a template-argument-list , the first non-nested > is taken as the ending delimiter rather than a greater-than operator. Similarly, the first non-nested >> is treated as two consecutive but distinct > tokens, the first of which is taken as the end of the template-argument-list and completes the template-id.”

C++11标准中,要求编译器对模板的右尖括号做单独处理,使编译器能够正确判断出“>>”是一个右移操作符还是模板参数表的结束标记(界定符)。

不过这种自动化的处理在某些时候会与老标准不兼容,比如下面这个例子:

C++98/03的编译器编译是ok的,但C++11的编译器会告诉你:

解决的方法是这样写:

这种加括号的写法其实也是一个良好的编程习惯,让我们在书写时倾向于写出无二义性的代码。

在C++11之前,各种C++98/03编译器除了支持标准(ISO/IEC 14882:2003及其之前的标准)之外,还自行做了不少的拓展。
这些拓展中的一部分,后来经过了C++委员会的斟酌和完善,进入了C++11。所以有部分C++11的新特征,在一些C++98/03的老编译器下也是可以支持的,只是由于没有标准化,无法保证各种平台/编译器下的兼容性。
比如像Microsoft Visual C++ 2005,虽然不支持C++11,但在对模板右尖括号的处理上和现在的C++11是一致的。

Published by orzz.org(). (http://orzz.org/template-specializations-in-cxx11/)

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据