博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ template 学习归纳总结4
阅读量:6927 次
发布时间:2019-06-27

本文共 4296 字,大约阅读时间需要 14 分钟。

我们在这篇文章来说说typename关键字吧。这个关键字是在c++的标准化过程中引入的,目的在于说明template中的某个表示符号是一个类型,而不是其他的东西,看下面的代码:

template 
class MyClass { typename T::SubType * ptr; … };

第一个typename我就不多说了,大家都知道,我来说一下第二个。他的意思是说T::SubType是class T内部定义的一个类型,从而ptr是一个指向【T:SubType类型】的指针。

如果在上面的代码中,没有第二个typename关键字的话,编译器会以为SubType是class Type的一个static成员。于是会被编译器理解为一个具体的东西,从而导致T::SubType * ptr 所表达的意思是两个数进行相乘。

关于这个知识的应用比较多的是STL中,比如:

#include 
// print elements of an STL container template
void printcoll (T const& coll) { typename T::const_iterator pos; // iterator to iterate over coll typename T::const_iterator end(coll.end()); // end position for (pos=coll.begin(); pos!=end; ++pos) { std::cout << *pos << ' '; } std::cout << std::endl; }

下面我们来看看另外一个有意思的问题。那就是”.template”,大家仔细查看下面的代码:

template
void printBitset (std::bitset
const& bs) { std::cout << bs.template to_string
, allocator
>(); }

大家注意到没有,。这个例子中的“.template”比较怪,但是如果没有他的话,那么编译器无法知道后面的“<”是模板参数的开始。而不是一个小于号。注意,只有当位于 点号之前的物件取决于某一个template parameter的时候,这种情况才会发生,以上的例子中,bs受控于N。也就是显式指明模板函数调用。可以理解为指名点姓的调用模板成员函数而非普通的。

结论是“.template”或者”->template”记号只能在templates中使用。而且他们必须紧跟在于template parameter相关的某个物件。

其实这里关于这个”.template”,笔者也没有搞懂,不知道哪位大牛搞懂了,麻烦指教一下,谢谢了。

下面我们来看看成员模板:

先看看下面的例子:

 

Stack
intStack1, intStack2; // stacks for ints Stack
floatStack; // stack for floats … intStack1 = intStack2; // OK: stacks have same type floatStack = intStack1; // ERROR: stacks have different types

默认的赋值运算要求左右两边拥有相等的类型。但是如果把赋值运算定义为一个模板,就可以使得类型不同,但是元素可以隐式转换,比如:

template 
class Stack { private: std::deque
elems; // elements public: void push(T const&); // push element void pop(); // pop element T top() const; // return top element bool empty() const { // return whether the stack is empty return elems.empty(); } // assign stack of elements of type T2 template
Stack
& operator= (Stack
const&); };

我们来实现它看看:关键代码如下:

template 
template
Stack
& Stack
::operator= (Stack
const& op2) { if ((void*)this == (void*)&op2) { // assignment to itself? return *this; } Stack
tmp(op2); // create a copy of the assigned stack elems.clear(); // remove existing elements while (!tmp.empty()) { // copy all elements elems.push_front(tmp.top()); tmp.pop(); } return *this; }

下面我们测试一下啊:

Stack
intStack; // stack for ints Stack
floatStack; // stack for floats … floatStack = intStack; // OK: stacks have different types, // but int converts to float

当然这个运算并不改变stack和其元素的类型,赋值完成转换,floatstack返回的任然是float。但是这个技术并不是说任何两个类型都能进行赋值,比如下面的代码就不行:

Stack
stringStack; // stack of ints Stack
floatStack; // stack of floats … floatStack = stringStack; // ERROR: std::string doesn't convert to float

你知道为什么了吗?

当然,和以前一样,你也可以在将内部容器的类型也参数化:

template 
> class Stack { private: CONT elems; // elements public: void push(T const&); // push element void pop(); // pop element T top() const; // return top element bool empty() const { // return whether the stack is empty return elems.empty(); } // assign stack of elements of type T2 template
Stack
& operator= (Stack
const&); };

此时的赋值运算实现代码为:

template 
template
Stack
& Stack
::operator= (Stack
const& op2) { if ((void*)this == (void*)&op2) { // assignment to itself? return *this; } Stack
tmp(op2); // create a copy of the assigned stack elems.clear(); // remove existing elements while (!tmp.empty()) { // copy all elements elems.push_front(tmp.top()); tmp.pop(); } return *this; }

转载地址:http://cgzjl.baihongyu.com/

你可能感兴趣的文章
告诉你 SQL 数据库与 NoSQL 数据库的区别
查看>>
一对好基友 - yii2行为和事件那些事 源码分析篇
查看>>
在 Java 中使用 redis 的消息队列服务
查看>>
5 分钟让你明白 “软链接” 和“硬链接”的区别
查看>>
Redux你的Angular 2应用--ngRx使用体验 | 掘金技术征文
查看>>
Angular 从 0 到 1 (四)史上最简单的 Angular 教程
查看>>
Volley源码解析
查看>>
数组去重
查看>>
深入理解e.target与e.currentTarget
查看>>
2018拼假指南
查看>>
8 - 博客文章详情页
查看>>
Redux 学习总结笔记
查看>>
JS异步与性能(一)
查看>>
Android Jetpack - Fragment官方说明
查看>>
ThinkPHP v5 新漏洞攻击案例首曝光,阿里云已可告警并拦截
查看>>
微服务架构方案 ZeroC IceGrid
查看>>
浅谈前端响应式设计(一)
查看>>
Log4j各级别日志重复打印的问题
查看>>
flask文件上传
查看>>
[Python3网络爬虫开发实战] 7-动态渲染页面爬取-2-Splash的使用
查看>>