在之前的代码示例中,频繁用到 typename
关键字。
它的作用就是声明模板参数是类型参数(对于非类型参数,之前的文章也有提到了),也可以用 class
关键字来代替,但为了避免歧义,大多还是使用 typename
了。
除此之外,在模板的定义也可以使用 typename
关键字,用来指定变量的类型。
举个例子:
1class Foo{
2public:
3 typedef int num;
4 static int order;
5};
6
7int main(){
8 Foo::num a = 10;
9 Foo::order = 10;
10 return 0;
11}
以上定义了一个类 Foo ,并且在类中定义了一个类型别名 Foo::num
,后续我们可以使用该类型别名。
同时也定义了一个类变量 order
,后续也可以直接使用该类变量。
类变量和类中声明的别名使用方式有相似之处,都是通过 XX::XX
的形式使用,但一个是变量,一个是类型名称,这是两者的根本差别。
假设现在定义了如下的 MyClass 类模板:
1template<typename T>
2class MyClass {
3private:
4 T::num * a;
5};
由于类变量和类中别名的相似之处,此时编译器将不知道 T::num 到底是变量还是类型,如果是变量的话,加上后面的 * 号会被当成是一个乘法操作。
这时就需要在类模板定义中使用 typename
关键字指定 T::num 是一个类型而不是变量。
如下所示:
1template<typename T>
2class MyClass {
3private:
4 typename T::num * a;
5};
通常而言,当某个依赖于模板参数的名称是一个类型时,就应该使用 typename
。
一个典型的应用就是在模板代码中访问 STL 容器的迭代器:
1template<typename T>
2void printcoll(T const &coll) {
3 typename T::const_iterator pos;
4 typename T::const_iterator end(coll.end());
5
6 for (pos = coll.begin(); pos != end; pos++) {
7 std::cout << *pos << std::endl;
8 }
9}
原创文章,转载请注明来源: C++ 模板系列小结03-在模板中指定变量类型
相关文章
- C++ 模板系列小结02-非类型模板参数
- C++ 模板系列小结01-函数模板和类模板
- C++ 标准容器库小结
- 从零打造渲染引擎系列01-什么是渲染引擎
- iOS开发 - 在 Swift 中去调用 C/C++ 代码
留言