我是靠谱客的博主 炙热冬瓜,最近开发中收集的这篇文章主要介绍条款42:了解typename的双重意义。,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在模板的的声明中,class与typename是没有什么区别的:

template <typename T> T func1(const T&);
template <class T> T func2(const T&);

但是在模板的定义中typename有时候却会派上用场。为了说明问题,我们先了解一下两个名词:从属名称和非从属名称。从属名称是依赖于某个类型的,比如迭代器,它是依赖于你的容器类型的;而非从属名称就不依赖其他类型,比如int。有了这两个基本概念之后我们就可以看一下例子了:
假设我们要打印一个容器(里面为)中的第二个元素,那么函数应该是这样:

template <typename C> void print2nd(const C& container)
{
	if(container.size() >= 2)
	{
		C::const_iterator iter(container.begin());
		++iter;
		std::cout<<*iter;
	}
}
其中的C::const_iterator,就依赖与传进去的容器的类型。虽然对于这个例子可以成功,但是还是要强调,对于从属名称(这里是C::const_iterator)最好在前面加上typename ,这样可以确保编译器将它看做一个类型名而不是其他什么的。举一个例子,如果是定义为一个指向迭代器的指针:

	if(container.size() >= 2)
	{
		
		typename C::const_iterator iter(container.begin());
		typename C::const_iterator* pIter = &iter;
		++(*pIter);
		std::cout<<*(*pIter)<<endl;
	}
如果却掉typename 就不行了,为什么呢?因为编译器总是会假设你遇到的不是一个类型就会把指针类型*当做乘号,然后就错了。
但是总有例外:typename不能出现在基类列表的嵌套从属类型之前,也不可出现在成员初始化列表中作为类型的限定符。
最后,为了获得迭代器所指的类型,可以通过typename std::iterator_traits<C::const_iterator>::value_type temp(*iter);来实现;而且最好是使用typedef来简化代码:

		typedef typename std::iterator_traits<C::const_iterator>::value_type type;
		type tmp = (*iter);

总之,当声明模板参数时,typename与class可以互换,而在模板中定义从属名称时,则只能使用typename,但是在基类列表和成员初始哈列表中,不能使用typename来指明从属名称。


最后

以上就是炙热冬瓜为你收集整理的条款42:了解typename的双重意义。的全部内容,希望文章能够帮你解决条款42:了解typename的双重意义。所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部