详解C++模板编程中typename用法

 更新时间:2021年07月07日 10:26:58   作者:Erice_s  
typename在C++类模板或者函数模板中经常使用的关键字,此时作用和class相同,只是定义模板参数,下面通过例子给大家介绍c++模板typename的具体用法,一起看看吧

typename的常规用法

typename在C++类模板或者函数模板中经常使用的关键字,此时作用和class相同,只是定义模板参数;在下面的例子中,该函数实现泛型交换数据,即交换两个数据的内容,数据的类型由_Tp决定。

template <typename _Tp>
inline void swap(_Tp& __a, _Tp& __b) 
{
  _Tp __tmp = __a;
  __a = __b;
  __b = __tmp;
}

typename的第二个用法:修饰类型

限定名和非限定名

​ 限定名(qualified name),是限定了命名空间的名称。看下面这段代码,cout和endl是在命名空间std定义的,必须加上std::,使其为std::cout和std::endl,因此称其为限定名。

#include <iostream>

int main()  
{
    std::cout << "Hello world!" << std::endl;
}

若在主函数前面使用using namespace std;或者在主函数内使用using std::cout;,然后使用时只用cout和endl,它们的前面不再有空间限定std::,所以此时的cout和endl叫做非限定名(unqualified name)。

#include <iostream>
using namespace std;

int main()  
{
    using std::cout;
	using std::endl;
	cout << "Hello world!" << endl;
}

依赖名和非依赖名

依赖名(dependent name)是指依赖于模板参数的名称,而非依赖名(non-dependent name)则相反,指不依赖于模板参数的名称。看下面这段代码:

template <class T>
class MyClass 
{
     int i;
     vector<int> vi;
     vector<int>::iterator vitr;
  
     T t;
     vector<T> vt;
     vector<T>::iterator viter;
 };

因为int是内置类型,前三个定义的类型在声明这个模板类时就已知,叫做非依赖名。然而对于接下来的三行定义,只有在模板实例化时才能知道它们的类型,因为它们都依赖于模板参数T。则T, vector<T>, vector<T>::iterator称为依赖名。

类作用域

在类外部访问类中的名称时,可以使用类作用域操作符,调用通常存在三种:静态数据成员、静态成员函数和嵌套类型:Metadata::value,Metadata::function,Metadata::ValueType;

 class Metadata {
     static int value;
     static int function();
     typedef std::string ValueType;
 };

下面来看一个例子:

template <class T>
void function()
{
	T::iterator *iter;
	.....
}

我们可能本意是想定义一个迭代器对象,例如我们如果用vector来实例化这个模板,那么iter
则应该是一个迭代器指针,但是,如果我们用下面这个类来实例化这个模板

class cType
{
    static int iterator;
    ...
};

/* 
T::iterator *iter会被编译器解释为两个数相乘。事实上,C++编译器会采用第二种解释方法,即使iterator的确是一个类型名。
为了避免这种矛盾,当我们适用qualified dependent name的时候,需要用typename来指出这是一个类型名.即: typename T::iterator *iter;
typename 指出下面紧跟着的名称是一个类型
*/
template <typename T> class Y
{
    typename T::iterator *iter;
    typedef typename T::iterator iterator; //定义了Y::iterator类型名称
    ...
};

T::iterator这种名称,由于iterator具体是类型还是成员变量取决于T的类型实现,所以当我们知道T::iterator是个类型名称时,如果我们要使用这个类型名,前面必须要加typename.

typename使用规则

typename在下面情况下禁止使用:

  1. 模板定义之外,即typename只能用于模板的定义中
  2. 非限定类型,比如int,vector<int>之类
  3. 基类列表中,比如template <class T> class C1 : T::InterType不能在T::InterType前面加typename
  4. 构造函数的初始化列表中,如果类型是依赖于模板参数的限定名,那么在它之前必须加typename(除非是基类列表,或者在类的初始化成员列表中)。

到此这篇关于详解C++模板编程中typename用法的文章就介绍到这了,更多相关c++模板typename内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++中vector容器的常用操作方法实例总结

    C++中vector容器的常用操作方法实例总结

    vector容器一般被用作创建动态数组,动态数组就像Python中的list结构一样,可以比普通数组拥有更丰富操作方法,下面就为大家整理了一些最常用的操作:
    2016-05-05
  • C++实现简单的图书管理系统

    C++实现简单的图书管理系统

    本文给大家分享的是使用C++实现简单的图书管理系统的代码,本系统采用了面向对象的程序设计方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2015-08-08
  • 利用C++求绝对值的几种方法例子

    利用C++求绝对值的几种方法例子

    相信大家在学习C++时,应该都有做过求绝对值的题目,下面这篇文章主要给大家介绍了关于利用C++求绝对值的几种方法例子,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-04-04
  • C/C++后端学习与练习深入

    C/C++后端学习与练习深入

    这篇文章主要介绍了C/C++对于后端的学习与练习,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • C++插入排序算法实例

    C++插入排序算法实例

    这篇文章主要介绍了C++插入排序算法实例,本文先是讲解了什么插入排序,然后给出了C++代码实例,需要的朋友可以参考下
    2014-10-10
  • C++ Boost log日志库超详细讲解

    C++ Boost log日志库超详细讲解

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
    2022-11-11
  • Qt开发之获取电脑磁盘容量

    Qt开发之获取电脑磁盘容量

    项目中用到了监测某磁盘(如:C盘、D盘等)的总容量和可用容量,查了一下,发现其实挺简单,本文就来用QT实现这一功能吧,希望对大家有所帮助
    2023-04-04
  • 解析如何在C语言中调用shell命令的实现方法

    解析如何在C语言中调用shell命令的实现方法

    本篇文章是对如何在C语言中调用shell命令的方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++中继承基类与派生类的区别

    C++中继承基类与派生类的区别

    这篇文章主要介绍了C++中继承基类与派生类的区别,面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易,需要的朋友可以参考下
    2023-05-05
  • 用C语言实现链式栈介绍

    用C语言实现链式栈介绍

    大家好,本篇文章主要讲的是用C语言实现链式栈介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12

最新评论