C++ 模板系列小结03-在模板中指定变量类型

技术答疑,成长进阶,可以加入我的知识星球:音视频领域专业问答的小圈子

在之前的代码示例中,频繁用到 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}
CPP

以上定义了一个类 Foo ,并且在类中定义了一个类型别名 Foo::num ,后续我们可以使用该类型别名。

同时也定义了一个类变量 order ,后续也可以直接使用该类变量。

类变量和类中声明的别名使用方式有相似之处,都是通过 XX::XX 的形式使用,但一个是变量,一个是类型名称,这是两者的根本差别。

假设现在定义了如下的 MyClass 类模板:

1template<typename T>
2class MyClass {
3private:
4    T::num * a;
5};
CPP

由于类变量和类中别名的相似之处,此时编译器将不知道 T::num 到底是变量还是类型,如果是变量的话,加上后面的 * 号会被当成是一个乘法操作。

这时就需要在类模板定义中使用 typename 关键字指定 T::num 是一个类型而不是变量。

如下所示:

1template<typename T>
2class MyClass {
3private:
4   typename T::num * a;
5};
CPP

通常而言,当某个依赖于模板参数的名称是一个类型时,就应该使用 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}
CPP

欢迎关注微信公众号:音视频开发进阶

Licensed under CC BY-NC-SA 4.0
粤ICP备20067247号
使用 Hugo 构建    主题 StackedJimmy 设计,Jacob 修改