C++模版中的typename关键字和嵌套依赖类型(依赖名称)

关于C++中模版常用的的typename和class,先写结论吧:

  • 在声明模版参数时,class和typename关键是等价的,可以相互替换。
  • 在涉及“嵌套依赖类型名”(nested dependent type name)的时候,必须用typename关键字去标识。
  • 规则2有个例外,就是在继承列表或者成员初始化列表中的基类初始化时,可以不用typename去标识“嵌套依赖类型”。
在早期的C++标准中,模版参数的关键字是通过class来标识的,后来引入了typename关键字。typename关键字本质上是标识一个类型,所以在模版参数定义时可以代替class。然而typename关键字有更重要的作用,即用来标识“嵌套依赖类型”,那么什么是“嵌套依赖类型”【有时也称为依赖名称或依赖类型,指这个名称依赖于模版参数T,可以通过比较“限定性名称”来理解,“限定性名称”是指由具体的类作为前缀,也就是这个名称在具体的类中,使用是需要具体的类加双冒号作为前缀来引用】,可以看下面一个例子:
?
1
2
3
4
5
6
template < typename T>
void print2nd( const T& container)
{
     T::const_iterator * x;
     ...
}
在print2nd这样一个模版函数中,变量x的类型依赖于模版参数T,因此它的具体类型只有在编译时的模版推导过程(template deduction)中才能够被确定。这样的类型称之为“嵌套依赖类型”(nested dependent type name),但是很遗憾,编译器并不知道const_iterator是一个类型还是一个静态变量。在默认情况下,C++标准会让编译器会把const_iterator做为一个静态变量处理(你没看错,编译器很多时候比我们想象的愚蠢),所以你会得到如下的编译错误:
?
1
2
3
leoxiang@debian:~$ g++ -std=c++0x test .cpp
test .cpp: In function ‘void print2nd(const T&)’:
test .cpp:16: error: ‘x’ was not declared in this scope
这时候,就需要typename关键字出场了,它显式的告诉编译器T::const_iterator是一个类型,因此这一行的语义就是声明一个嵌套依赖类型的局部变量,而不是一个静态变量乘以x。
?
1
2
3
4
5
6
template < typename T>
void print2nd( const T& container)
{
     typename T::const_iterator * x;
     ...
}
好了,最后说一个不需要使用typename的例外:就是在继承列表或者成员初始化列表中的基类初始化时,可以不用typename去标识“嵌套依赖类型”。说起来比较绕,看例子就明白了:
?
1
2
3
4
5
6
7
8
9
10
template < typename T>
class Derived: public Base<T>::Nested //in base class list, no typename
{
  public :
   explicit Derived( int x)
  : Base<T>::Nested(x) //in member init list, no typename
  {
    typename Base<T>::Nested temp; //nested dependent type, need typename
  }
};

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值