typename的作用

一、与class的区别

template声明式中,class和typename这两个关键字意义完全相同

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

二、什么时候要用typename?比如下面的代码

template <typename C> 
void print2nd(const C& container) 

    if (container.size() >= 2) 
    { 
        C::const_iterator iter(container.begin()); 
        ++iter; 
        int value = *iter; 
        std::cout << value; 
    } 
}

关键的地方在于C::const_iterator这个到底是什么?是类中的一个静态成员变量还是类中的嵌套从属名称?这取决于模板的参数C

这里的iterator就是嵌套从属名称
template <class T> 
 class test 
 { 
 vector <T> xx; 
 typename vector <T> ::iterator Iterator ; <=====这里必须加typename 
 }; 
在这里因为在编译期无法知道T是什么,也就无法确定iterator是否为某种类型,为了告诉编译器它是一种类型,必须在前面添加typename 

三、嵌套从属名称可能导致解析的困难

template <typename C> 
void print2nd(const C& container) 

    C::const_iterator* x; 
}

这里有可能让编译误导是参数C中的某个静态成员变量与变量x作相乘,所以这里必须在前面添加typename

 

四、不该使用typename的地方

1、typename只用来验明嵌套从属类型名称;其他名称不该有它存在。

template <typename C> 
void f(const C& container, //不允许使用typename 
       typename C::iterator iter);//一定要使用typename
 

2、“typename必须作为嵌套从属类型名称的前缀词”这一规则的例外是,typename不可以出现在base classes list内的嵌套从属类型名称之前,也不可在member initialization list(成员初始化列表)中作为base class修饰符。

template <typename T> 
class Derived: public Base<T>::Nested{//base class list中不允许“typename” 
public: 
    explicit Derived(int x) 
        :Base<T>::Nested(x)//mem.init.list中不允许“typename” 
    { 
       typename Base<T>::Nested temp;//嵌套从属类型既不在base class list中也不在mem.init.list中, 
    }                                                         //作为一个base class修饰符需加上typename 
};

 

五、typename的使用例子

让我们看一个typename例子:一个function template,他接受一个迭代器,而我们打算为该迭代器指涉的对象做一份复件temp:

template <typename IterT> 
void workWithIterator(IterT) 

    typename std::iterator_traits<IterT>::value_type temp(*iter); 
}

也可以这么写,可以少打几个typedef typename std::iterator_traits<IterT>::value_type

template <typename IterT> 
void workWithIterator(IterT) 

    typedef typename std::iterator_traits<IterT>::value_type value_type; 
    value_type temp(*iter); 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/463303.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[转]详细讲解提高数据库查询效率的实用方法、外键关于性能

1.对查询进行优化&#xff0c;应尽量避免全表扫描&#xff0c;首先应考虑在 where 及 order by 涉及的列上建立索引。 2.应尽量避免在 where 子句中对字段进行 null 值判断&#xff0c;否则将导致引擎放弃使用索引而进行全表扫描&#xff0c;如&#xff1a; select id from t w…

C语言 scanf()和gets()函数的区别

C语言 scanf()和gets()函数的区别 1.相同点&#xff1a;scanf( )函数和gets( )函数都可用于输入字符串 2.不同点&#xff1a;两者在功能上有所区别,具体区别如下&#xff1a; 要实现如下需求“从控制台输入字符串”有如下两种实现方式&#xff1a; 1>使用gets()函数实现使用…

静态链接库与动态链接库的区别

(1)、静态链接库&#xff1a;在链接阶段(生成可执行文件)将库函数全部载入到可执行文件中&#xff0c;可执行文件中包含了所有的库函数 优点&#xff1a;应用程序可以独立运行&#xff1b; 缺点&#xff1a;如果多次调用库中的函数&#xff0c;则该库函数会被调用多次 (2)、动…

用C语言实现SGF格式围棋棋谱解析器

这是本人&#xff08;liigo&#xff09;独立实现的SGF格式围棋棋谱文件解析器&#xff0c;本文介绍其实现细节。网络上肯定可以找到完善的开源的SGF解析器&#xff0c;这是毋庸置疑的&#xff0c;我不直接使用它们&#xff0c;也不参考它们的实现代码&#xff0c;而是自己独立编…

各种***方式说明

使消息保密的技术和科学叫做密码编码学&#xff08;cryptography&#xff09;。密码编码学是密码体制的设计学&#xff0c;即怎样编码&#xff0c;采用什么样的密码体制以保证信息被安全地加密。从事此行业的人员叫做密码编码者&#xff08;cryptographer&#xff09;。 与之相…

C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区

C内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区栈&#xff0c;就是那些由编译器在需要的时候分配&#xff0c;在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。在一个进程中&#xff0c;位于用户虚拟地址空间顶部的是用…

Uoj 441 保卫王国

Uoj 441 保卫王国 动态 \(dp\) .今天才来写这个题.设 \(f[u][0/1]\) 表示子树 \(u\) 中不选/选 \(u\) 时的最小权值和,显然有:\(f[u][0]\sum f[v][1] ,f[u][1]w[u]\sum \min(f[v][0],f[v][1])​\) .现在要资瓷修改 \(x\) 的点权 \(w[x]\) ,容易发现修改后只会影响 \(x\) 到根节…

行存和列存的区别

写入&#xff1a; 行存储的写入是一次完成&#xff0c;数据的完整性因此可以确定。 列存储需要把一行记录拆分成单列保存&#xff0c;写入次数明显比行存储多。 行存储在写入上占有很大的优势 数据修改&#xff1a; 行存储是在指定位置写入一次&#xff0c;列存储是将磁盘定位…

javascript中的命名规则和方法

javascript变量名需要遵守两条简单的规则&#xff1a;1、第一个字符必须是字母、下划线&#xff08;_&#xff09; 或美圆符号&#xff08;$&#xff09;。2、余下的字符可以是下划线、美圆符号或任何字母或数字字符。 命名方法&#xff1a;1、Camel标记法——首字母是小写的&a…

jquery插件开发导读

最近发现项目中有些js代码可以重用&#xff0c;但是不知道怎么样组织&#xff0c;在网上调研后&#xff0c;发现jquery插件是一种很好的组织方式&#xff0c;而且项目也采用了jquery框架&#xff0c;所以花了点时间学习jquery插件开发&#xff0c;并且动手将部分项目代码转成jq…

C语言缓冲文件系统和非缓冲文件系统

C 语言所使用的磁盘文件系统有两大类&#xff1a;一类称为缓冲文件系统&#xff0c;又称为标准文件系统&#xff1b;另一类称为非缓冲文件系统。缓冲文件系统的特点是系统自动地在内存区为每一个正在使用的文件开辟一个缓冲区。从磁盘向内存读入数据时&#xff0c;则一次从磁盘…

Swift 里集合类型协议的关系

&#xfffc; &#xfffc; Sequence A type that provides sequential, iterated access to its elements. 是最基础的协议&#xff0c;可以通过迭代来获取它的元素。 有两个关联类型&#xff1a; /// A type representing the sequences elements.associatedtype Element//…

ASP.NET 实现登录界面(生成验证码)

这周末也没干啥&#xff0c;真正开始ASP&#xff0c;做了个学籍管理系统的登录界面&#xff0c;登录界面主要包括用户名、密码、验证码&#xff0c;界面字体用了<font size"5" color"blue" font-family:"华文琥珀";></font>改变字体…

C/C++语言void及void指针深层探索

1.概述  许多初学者对C/C语言中的void及void指针类型不甚理解&#xff0c;因此在使用上出现了一些错误。本文将对void关键字的深刻含义进行解说&#xff0c;并详述void及void指针类型的使用方法与技巧。2.void的含义  void的字面意思是“无类型”&#xff0c;void *则为“无…

多域资源整合之基础准备--DNS配置

由于公司的战略调整,需要整合集团内的资源,当然也也包含IT资源,我们需要评估多家公司的IT架构统一,顺利的合并到总集团的IT架构里,这也就产生一个多域的整合的一个案例,在此分享给大家,希望对大家有所帮助&#xff01;篇幅较长&#xff0c;让我们慢慢细化&#xff01; 在这次的…

python__实参前加*和**的(拆包)功能

print(--------元组打散--------) tup(1,2,3) print(tup) print(*tup) print(--------列表打散--------) list[1,2,3] print(list) print(*list) print(--------字符串打散------) strhello print(str) print(*str) print(--------字典打散--------) def func_dic(name,age):pr…

内存淘汰机制 LRU cache

LRU cache机制的目的是为了减少频繁查找的开销&#xff0c;包括磁盘IO等。 (1)、如果LRU中存在则从LRU缓存中查找&#xff0c;查找到了之后放到容器(list)的最前面 (2)、如果缓存中没有&#xff0c;则从其地方(数据库、磁盘、文件)中读取&#xff0c;读取之后放到容器的最前面…

字符与字符串操作——Windows via C/C++

在最新版的Windows, Windows Vista&#xff0c;它应该支持Unicode 5.0。在编程中对字符与字符串的操作是很普通的&#xff0c;为新的系统写代码&#xff0c;尽可能使用Unicode&#xff0c;它提供了更好的性能&#xff0c;以及可以进行区域化。而且与COM及.Net框架互操作时也有帮…

cmd常用命令总结

CMD命令&#xff1a;开始&#xff0d;>运行&#xff0d;>键入cmd或command&#xff08;在命令行里可以看到系统版本、文件系统版本&#xff09;chcp 修改默认字符集chcp 936默认中文chcp 650011. appwiz.cpl&#xff1a;程序和功能 2. calc&#xff1a;启动计算器 5. ch…

生产者-消费者模式的实现

// 生产者-消费者模式 无锁队列 get()时&#xff0c;如果deque里面没有元素了&#xff0c;则会一直阻塞,还有待改进的空间 template <class T> class BlockingQueue { public:explicit BlockingQueue() : shutdown_(false) {}~BlockingQueue() {}void put(const T&a…