typename的正确使用

typename的正确使用

一、在声明模板参数时,class typename 是可互换的。

以下完全等价:

template<class T> class Widget;
template<typename T> class Widget;

 

二、通常情况下,必须用 typename 去标识嵌套依赖类型名,但在基类列表中或在一个构造函数的成员初始化列表中作为一个基类标识符时除外。

 

template<typename C>
void print(const C& obj)

C::const_iterator *x; // 无法编译,带::的默认不是类型名

}
}

::的默认不是类型名。所以,编译器会把C::const_iterator * x理解为C中一个名为const_iterator的变量剩以x

iter 的类型是 C::const_iterator,一个依赖于模板参数C 的类型。一个模板中的依赖于一个模板参数的名字被称为依赖名字。当一个依赖名字嵌套在一个 class(类)的内部时,我称它为嵌套依赖名字,即::前是模板参数名或依赖于模板参数的类型名时。C::const_iterator是一个 nested dependent name(嵌套依赖名字)。实际上,它是一个 nested dependent type name(嵌套依赖类型名),也就是说,一个涉及到一个 type(类型)的 nested dependent name(嵌套依赖名字)。直到 C 成为已知之前,没有任何办法知道 C::const_iterator 到底是不是一个 type(类型),而当 template(模板)print被解析的时候,C 还不是已知的。

正确的做法:在嵌套依赖名字前用typename明确告诉编译器C::const_iterator是一个 type(类型):

template<typename C> // this is valid C++
void print2nd(const C& container)
{
if (container.size() >= 2) {

typename C::const_iterator * x;
//typedef typename C:: const_iterator ConIt;
这也是一种常见做法,typedef后用typename

}
}

该规则有2个例外:

typename 不必前置于在一个 list of baseclasses(基类列表)中的或者在一个 memberinitialization list(成员初始化列表)中作为一个 base classes identifier(基类标识符)的 nested dependenttype name(嵌套依赖类型名)。例如:

template<typename T>
class Derived:
public Base<T>::Nested
// base class list: typename not
public: // allowed
explicit Derived(int x)
: Base<T>::Nested(x) // baseclass identifier in mem

// init. list: typename not allowed

typename Base<T>::Nested temp; // use of nesteddependent type
... // name not in a base class list or
} // as a base class identifier in a
... // mem. init. list: typename required
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值