C++模板中关键字typename与class的区别

C++模板中关键字typename与class的区别

一.共同点

在定义类模板或者函数模板时,typenameclass 关键字都可以用于指定模板参数中的类型。

template <typename T>
template <typename N>

二.typename独有的功能

由于 C++ 允许在类内定义类型别名,且其使用方法与通过类型名访问类成员的方法相同。故而,在类定义不可知的时候,编译器无法知晓类似 Type::foo 的写法具体指的是一个类型还是类内成员。

例如在以下代码中,类模板 Bar 的原意是使用类 Foo 实例化,而后引用其中的 bar_type 定义名为 bar 的类内成员。然而,就 T::bar_type 而言,编译器在编译期无法确定它究竟是不是一个类型。此时就需要 typename 关键字来辅助编译器的判断。

class Foo 
{
 public:
  typedef int bar_type;
};

template<typename T>
class Bar {
 /* typename */
 T::bar_type bar;
};

值得一提的是,在编译期能够判断的情形,例如在上例中直接使用 Foo::bar_type 时,使用冗余的 typename 会报错。

class独有的功能

class 关键字最众所周知的功能是声明或定义一个类。这当然是其相对 typename 的一个独有功能。为了完整性,这里也列出。

除此之外,在模板的使用中,class 关键字也有其特有的功能。而这是绝大多数文章不会提及的。

C++ 的标准模板库中有名为 std::stack 的容器适配器,它能适配许多容器作为底层,实现栈的功能。其声明为

template <typename T, typename Containter = std::deque<T> >
class stack;

因此,在使用中,我们可以使用 std::stack<int> 来声明一个以 std::deque<int> 保存整型变量的栈;也可以使用 std::stack<int, std::vector<int> > 来声明一个以 std::vector<int> 保存整型变量的栈。

现在的问题是,是否有可能以类似 Stack<int, std::vector> 的形式,来达到同样的目的?

为此,我们需要有类似这样的声明

template <typename T,
    template <typename E, typename = std::allocater<E> > class Container = std::deque>
class Stack;

由于 Container 必须是一个容器类模板,所以,如果不适用具体的模板参数实例化,就必须将其声明为一个类模板。故此,Container 之前需要保留标准库中容器类模板的模板参数。注意此处使用了标准库提供的内存分配器。

此处 class 特有的功能,体现在 class Container 之处。此处虽然是在声明 Stack 这个类模板,但是此处的 class 不能替换为 typename;否则编译器会报错。

  • 20
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值