C++教程 扩展标准库第一部分

  今天给大家带来的是C++扩展标准库的一些知识点的讲解!这是一部分,后面还会更新另外的一部分!

  ok,今天我们说另一个小工具,这个工具在处理一些复杂数据的时候会有一些意想不到的效果,不过这得和大家说一些,我是一个标准的标准库忠实者,所以我写程序基本都会优先考虑库,然后在世boost库,而接下来的东西我会借助标准库的东西进行扩展的。

  既然是标准库的扩展,那么第一步我们可以先将标准库的东西再进行一些简化,当然这些简化只是为了我们在调试程序的时候方便使用一些。

  C++的标准输出输入流为了简便都提供了一个操作符(<<)用来输出(>>)用来输入,所以为了简便,我们可以先将C++里面的标准容器都让它们带有这种流式操作,就比如:

  //====================================

  std::vector v;

  v<<1<<2<<3<<4.......; //将数据压入容器中

  int a,b,c,d;

  v>>a>>b>>c>>d; //将容器中的元素从后到前依次提取

  //======================================

  让容器变得这么简便随便提供不了多大的好处,但是要是你习惯这样的编程习惯后你就会发现这样做其他也是挺好的,ok,那么第一步,我们先来将该功能实现。

  要实现上面的功能大家第一步可能已经想到了,也许是下面这样:

  //=====================================

  template

  inline std::vector& operator<<(std::vector& v, const T& value){

  v.push_back(value);

  return v;

  }

  template

  inline std::vector& operator>>(std::vector& v, T& value){

  if (v.empty()){

  value = T();

  }

  else{

  value = v.back();

  v.pop_back();

  }

  return v;

  }

  //========================================

  确实,我们可以这么实现,而且工作得挺好,如果我们想要操作的是list的话,那么我们再实现一个list版本的即可:

  //========================================

  template

  inline std::list& operator<<(std::list& l, const T& value){

  l.push_back(value);

  return l;

  }

  template

  inline std::list& operator>>(std::list& l, T& value){

  if (l.empty()){

  value = T();

  }

  else{

  value = l.back();

  l.pop_back();

  }

  return l;

  }

  //==========================================

  ok,这是list的流式操作也出来了,那么如果容器是队列呢............嗯,就算全部写出来也不算多了,因为标准库里面的容器其实也就这么几个了,但是如果有很多呢......

  好吧,不知道大家还能够想起以前给大家说的关于模板的一些高级技巧没,如果想不起,没关系,可以回头去看看,大概在90讲左右,如果都已经熟悉那就更好不过,因为我们可以使用更简单的方式来实现这种简便的操作,那就是使用模板的模板参数,首先我们可以肯定的知道不管是vector还是list,又或者是deque他们都有一个共同的特点,就是使用push_back来把数据压入容器,使用pop_back函数来将数据从后面弹出,所以我们只需要两个函数就能够完成对这三个标准容器的流式操作了,如下:

  //==========================================

  template class C>

  C& operator<<(C& c, const T& value){

  c.push_back(value);

  return c;

  }

  template class C>

  C& operator>>(C& c, T& value){

  if (c.empty()){

  value = T();

  }

  else{

  value = c.back();

  c.pop_back();

  }

  return c;

  }

  //==========================================

  ok,使用模板就是这么方便,这里我们使用的是模板的模板参数这一技巧。下面是set的实现:

  //===========================================

  template class S>

  S& operator<<(S& c,const T& value){

  c.insert(value);

  return c;

  }

  template class S>

  S& operator>>(S& c, T& value){

  if (c.empty()){

  value = T();

  }

  else{

  auto it = --c.end();

  value = *(it);

  c.erase(it);

  }

  return c;

  }

  //================================================

  由于set和vector他们的操作不一样,所以写法稍微有些不一样,对于map倒是和set差不多的了:

  //===============================================

  template

  template class M>

  M& operator<<(M& m, const std::pair& p){

  m.insert(p);

  return m;

  }

  template

  template class M>

  M& operator>>(M& m, std::pair& p){

  if (m.empty()){

  p = std::make_pair(K(), V());

  }

  else{

  auto it = --m.end();

  p = *it;

  m.erase(it);

  }

  return m;

  }

  //================================================

  ok,到这里我们基本都对标准库一些常用的容器都进行了一次包装,那么接下来我们希望在调试程序的时候如果遇到一个容器,我们想要知道容器里面的是什么,为了方便,我们可能希望能够像操作基本类型一样的用流来操作容器,例如:

  //=================================================

  std::vector v;

  v << 1 << 2 << 3 << 4 << 5;

  std::cout<

  //==================================================

  要实现这个功能还是像上面一样简单,今天我们就用这个来做结尾,下一讲我们再继续:

  //===================================================

  //对vector,list deque的打印

  template class C>

  std::ostream& operator<<(std::ostream& os, const C& c){

  if (c.empty())

  return os;

  std::copy(c.begin(), --c.end(), std::ostream_iterator(os, ","));

  os << *(--c.end());

  return os;

  }

  //==================================================

  下面是对set的打印

  //==================================================

  template class S>

  std::ostream& operator<<(std::ostream& os, const S& c){

  if (c.empty())

  return os;

  std::copy(c.begin(), --c.end(), std::ostream_iterator(os, ","));

  os << *(--c.end());

  return os;

  }

  //==================================================

  对map的打印

  //=================================================

  template

  template class M>

  std::ostream& operator<<(std::ostream& os, const M& m){

  if (m.empty())

  return os;

  std::for_each(m.begin(), m.end(), [&](std::pair p){

  os << p.first << "," << p.second << ",";

  });

  return os;

  }

  //=================================================

时间: 2024-11-05 12:13:26

C++教程 扩展标准库第一部分的相关文章

标准库》第一章 Object对象

(本文为阮一峰js标准教程的学习笔记,旨在总结该教程中涉及的知识点大纲及个人所做的一些拓展,方便作为"目录"或者"大纲"复习和查漏补缺,详细内容请参见阮一峰教程原文) 第三部分 标准库 ****************第一章 Object对象****************** 一.概述1.js原生提供Object对象2.首字母大写其他所有对象都继承自这个对象,它相当于其他编程语言中基类这一层概念的体现,而其他由此派生的类都是子类Object本身也是一个构造函数,可

什么是 C 和 C ++ 标准库?

简要介绍编写C/C ++应用程序的领域,标准库的作用以及它是如何在各种操作系统中实现的. 我已经接触C++一段时间了,一开始就让我感到疑惑的是其内部结构:我所使用的内核函数和类从何而来? 谁发明了它们? 他们是打包在我系统中的某个地方吗? 是否存在一份官方的C ++手册? 在本文中,我将通过从C和C ++语言的本质到实际实现来尝试回答这些问题. C和C++是如何制订的 当我们谈论C和C++时,实际上是指一组定义(程序)语言应该做些什么,如何表现,应该提供哪些功能的规则.C/C++的编译器为了处理

Obstack是C标准库里面对内存管理的GNU扩展

Obstack介绍 Obstack初始化 在Obstack中申请对象 释放对象 申请growing object 获取Obstack状态 数据对齐 以下是来自wiki对obstack的介绍: Obstack是C标准库里面对内存管理的GNU扩展(实际上就是GNU C library了).Obstack===Object stack.没错,Obstack就是一个栈,栈里面的元素是对象object(不是面向对象的对象哦,这里的对象单指数据元素).这些数据是动态的,也就是使用的是动态内存.这种内存管理技

python基础教程_学习笔记15:标准库:一些最爱——fileinput

标准库:一些最爱 fileinput 重要的函数 函数 描述 input([files[,inplace[,backup]]) 便于遍历多个输入流中的行 filename() 返回当前文件的名称 lineno() 返回当前(累计)的名称 filelineno() 返回当前文件的行数 isfirstline() 检查当前行是否是文件的第一行 isstdin() 检查最后一行是否来自sys.stdin nextfile() 关闭当前文件,移动到下一个文件 close() 关闭序列 fileinput

python基础教程_学习笔记14:标准库:一些最爱——re

标准库:一些最爱 re re模块包含对正则表达式的支持,因为曾经系统学习过正则表达式,所以基础内容略过,直接看python对于正则表达式的支持. 正则表达式的学习,见<Mastering Regular Expressions>(精通正则表达式) re模块的内容 最重要的一些函数 函数 描述 compile(pattern[,flags]) 根据包含正则表达式的字符串创建模式对象 search(pattern,string[,flags]) 在字符串中寻找模式 match(pattern,st

python基础教程总结9——模块,包,标准库

1. 模块 在python中一个文件可以被看成一个独立模块,而包对应着文件夹,模块把python代码分成一些有组织的代码段,通过导入的方式实现代码重用. 1.1 模块搜索路径 导入模块时,是按照sys.path变量的值搜索模块,sys.path的值是包含每一个独立路径的列表,包含当前目录.python安装目录.PYTHONPATH环境变量,搜索顺序按照路径在列表中的顺序(一般当前目录优先级最高). 1 >>> import sys 2 >>> sys.path 3 ['

python基础教程_学习笔记19:标准库:一些最爱——集合、堆和双端队列

标准库:一些最爱 集合.堆和双端队列 集合 集合Set类位于sets模块中. >>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> set(range(10)) set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 集合是由序列(或其他可迭代的对象)构建的.主要用于检查成员资格,因此,副本是被忽略的: >>> range(10)*2 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9

[学习笔记] Python标准库简明教程 [转]

1 操作系统接口 os 模块提供了一系列与系统交互的模块: >>> os.getcwd() # Return the current working directory '/home/minix/Documents/Note/Programming/python/lib1' >>> os.chdir('~/python') # Change current working directory Traceback (most recent call last): File

《Python基础教程(第二版)》学习笔记 -&gt; 第十章 充电时刻 之 标准库

SYS sys这个模块让你能够访问与Python解释器联系紧密的变量和函数,下面是一些sys模块中重要的函数和变量: 函数和变量 描述 argv 命令行参数,包括脚本和名称 exit([arg])                退出当前的程序,可选参数为给定的返回值或者错误信息 modules 映射模块名字到载入模块的字典 path 查找模块所在目录的目录名列表 platform 平台标识符 stdin 标准输入流-- 一个类文件对象 stdout 标准输出流-- 一个类文件对象 stderr