c++ 为自定义类添加stl遍历器风格的遍历方式
为仿照stl的遍历风格,实现对自定义类型的遍历。
1. 需要遍历的基础结构:
struct ConnectionPtr
{
int id_;
int port_;
string addr_; //std::set 需要排序,需要重载<
bool operator <(const ConnectionPtr &ptr)const {
return id_ < ptr.id_;
} void printPtr() //显示函数
{
cout << "ConnectionPtr :" << endl;
cout << "id = " << id_ << " port = " << port_ << " addr_ = " << addr_ << endl;
cout << endl;
}
};
2. 需要实现统一风格遍历的自定义结构:
struct Region_connection
{
map<int, set<ConnectionPtr>> connections; //自定义结构
}
3. 遍历器的结构:
class RegionIterator
{
public:
int key;
ConnectionPtr* ptr;
map<int, set<ConnectionPtr>>* pconnections; RegionIterator(){
clear();
} //赋值
RegionIterator& operator = (const RegionIterator &iter)
{
key = iter.key;
ptr = iter.ptr;
}
//不等于
bool operator != (const RegionIterator &iter)
{
return (key != iter.key) || (ptr != iter.ptr);
}
//等于
bool operator == (const RegionIterator &iter)
{
return (key == iter.key) && (ptr == iter.ptr);
}
//前缀自加
RegionIterator& operator ++ ()
{
RegionIterator itor = next(key, ptr);
this->key = itor.key;
this->ptr = itor.ptr;
return *this;
}
//后缀自加
RegionIterator operator ++ (int)
{
RegionIterator tmp = *this;
RegionIterator itor = next(key, ptr);
this->key = itor.key;
this->ptr = itor.ptr;
return tmp;
}
//取值
ConnectionPtr& operator * ()
{
return *ptr;
} private:
void clear()
{
key = -;
ptr = nullptr;
pconnections = nullptr;
} RegionIterator next(int key_tmp, ConnectionPtr* ptr_tmp)
{
assert(pconnections);
RegionIterator region;
auto iter = pconnections->find(key_tmp);
if (iter != pconnections->end()){
const set<ConnectionPtr>& sets = iter->second;
if (sets.size()){
if (ptr_tmp){
auto itr = sets.find(*ptr_tmp);
if (itr != sets.end()){
if (++itr != sets.end()){
region.key = key_tmp;
region.ptr = (ConnectionPtr*)&*(itr);
return region;
}else{
if (++iter != pconnections->end()){
key_tmp = iter->first;
return next(key_tmp, nullptr);
}else{
return region;
}
}
}
else{
return region;
}
}else{
region.key = key_tmp;
region.ptr = (ConnectionPtr*)&(*sets.begin());
return region;
} }else{
assert(ptr_tmp == nullptr);
key_tmp = (++iter)->first;
return next(key_tmp, ptr_tmp);
}
}
else{
return region;
}
}
};
4. 为实现要求,需要在自定义结构添加部分函数:
struct Region_connection
{
map<int, set<ConnectionPtr>> connections; typedef RegionIterator iterator;
iterator begin(){
iterator itor;
itor.pconnections = &connections;
if (connections.size() > )
{
for (auto itr = connections.begin(); itr != connections.end(); itr++)
{
const set<ConnectionPtr>& sets = itr->second;
if (sets.size() > )
{
auto itr2 = sets.begin();
ConnectionPtr* p = (ConnectionPtr*)&(*itr2);
itor.key = itr->first;
itor.ptr = p;
return itor;
}
}
}
return iterator();
} iterator end(){
return iterator();
} ConnectionPtr& operator[](const RegionIterator& itor){
auto connect = connections.find(itor.key);
assert(connect != connections.end());
const set<ConnectionPtr>& sets = connect->second;
auto ptr = sets.find(*itor.ptr);
assert(ptr != sets.end());
return (ConnectionPtr&)*ptr;
} int size(){
int size = ;
for (auto itor : connections)
{
size += itor.second.size();
}
return size;
} };
5. 测试代码:
#include "stdafx.h" #include <iostream>
#include <map>
#include <set>
#include <string>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include "mylterater.h"
#include "regiontest.h"
#include <time.h> using namespace std; #define random(x,y) (((double)rand()/RAND_MAX)*(y-x)+x) int _tmain(int argc, _TCHAR* argv[])
{ srand((int)time());
//构造Region_connection
Region_connection region;
int n = ;
for (int i = ; i < random(,); i++)
{
set<ConnectionPtr> sets;
int num = random(, );
for (int j = ; j < num; j++, n++)
{
ConnectionPtr ptr;
ptr.id_ = n;
ptr.port_ = + n;
sets.insert(ptr);
}
region.connections.insert(std::make_pair(i, sets));
} //遍历打印
clock_t starttim, endtim;
starttim = clock();
for (auto iter = region.begin(); iter != region.end(); iter++)
{
ConnectionPtr& ptr = region[iter];//*iter;
ptr.printPtr();
}
endtim = clock();
cout << "Total time : " << endtim - starttim << " ms" << endl; getchar(); return ;
}
c++ 为自定义类添加stl遍历器风格的遍历方式的更多相关文章
- 添加登录装饰器的两种方式:FBV和CBV
1.FBV方式:添加验证装饰器 def auth(func): def deco(request, *args, **kwargs): u = request.get_signed_cookie('u ...
- Swift快速给Cocoa库内置类添加便捷初始化器
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Cocoa中的NSShadow类默认没有我们需要的实例方法,为 ...
- Qt自定义类添加qvector报错
PtsData& PtsData::operator=(const PtsData& obj){ return *this;} PtsData::~PtsData(){ }
- 遍历器Iterator--指针对象
一. 什么是遍历器 1. 遍历器对象(Iterator) 遍历器对象本质上是一个指针对象,该对象有一个next方法,调用next方法返回一个 含有value和done属性的对象{value: val/ ...
- Iterator(遍历器) 和 for...of 循环
是generator的前置知识 generator :https://www.cnblogs.com/wangtong111/p/11322961.html 遍历器(Iterator)就是这样一种机制 ...
- 疑问:Iterator 遍历器和数据集合各种遍历方法的区别
https://es6.ruanyifeng.com/#docs/iterator Iterator(遍历器)的概念 Iterator 接口主要供for...of消费 Iterator 的遍历过程是: ...
- <JVM中篇:字节码与类的加载篇>04-再谈类的加载器
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...
- runtime-给系统已有类添加属性
在没有接触runtime之前,我们接触到的能给类进行扩展的方法有类目(category)和延展(extension)两种.类目(category)可以给系统已有类添加扩展方法但是不能添加属性,并且被添 ...
- spring boot自定义类配置绑定在配置文件中自动提示
在spring boot的日常使用中,我们可能需要使用配置绑定的方式动态配置自定义类的成员变量. 这个时候,我们在配置文件中配置spring默认已有的配置时,只需要输入部分关键字即可自动提示,如下图: ...
随机推荐
- AI 概率论
概率论 不确定性 量化 频率 频率派 贝叶斯派 1.随机变量(random variable) 随机取不同值的变量,取值可以离散或者连续. 2.概率分布(probability distributio ...
- STL语法——集合:set 安迪的第一个字典(Andy's First Dictionary,UVa 10815)
Description Andy, , has a dream - he wants to produce his very own dictionary. This is not an easy t ...
- TCP/IP协议---ICMP协议及ping、traceroute
ICMP Internet控制报文协议通常被认为是IP层的组成部分,一般被IP层或更高层(TCP.UDP)使用.ICMP报文是在IP数据报内部被传输的.如图: ICMP报文的格式如下: 报文的前4个字 ...
- 快速排序的php实现
再来一个非常高级的排序算法,快速排序...这个算法是很高效的. 快速排序的思路是,找到一个分割点(中枢点 默认是列表第一个值),把原列表分隔成两部分,在分割点左侧的是都比它小的,在它右侧的是都比它大的 ...
- MFC入门(二)-- 提取输入框的字符串(定时关机的小程序)
上篇文章已经让我们有了对于MFC最简单直观的认识,但貌似并无太大的交互性可言,而且其实也没有涉及到数据的交互,所以本文通过做一个时间可以调节的定时关机的Demo来演示. MFC入门(一)地址:http ...
- 在平衡树的海洋中畅游(三)——Splay
Preface 由于我怕学习了Splay之后不直接写blog第二天就忘了,所以强行加了一波优先级. 论谁是天下最秀平衡树,我Splay第一个不服.维护平衡只靠旋转. 一言不合转死你 由于平衡树我也介绍 ...
- maven项目中 org.hibernate.MappingNotFoundException: resource:*.hbm.xml not found问题的解决方案
是因为*.hbm.xml没有放到resource的mapper下导致的 对于Maven工程,编译的工作是由Maven程序来完成的,而Maven默认只会把src/main/resources文件夹下的文 ...
- [UWP 自定义控件]了解模板化控件(5.2):UserControl vs. TemplatedControl
1. UserControl vs. TemplatedControl 在UWP中自定义控件常常会遇到这个问题:使用UserControl还是TemplatedControl来自定义控件. 1.1 使 ...
- Zabbix监控系统部署:前端初始化
1. 概述 在上一篇博客<Zabbix监控系统部署:源码安装.md>中,主要进行了zabbix最新版的源码编译安装. (博客园地址:https://www.cnblogs.com/liwa ...
- GlusterFS分布式存储学习笔记
分布式文件系统 分布式文件系统(Distributed File System)是指文件系统管理的物理存储资源并不直接与本地节点相连,而是分布于计算网络中的一个或者多个节点的计算机上.目前意义上的分布 ...