为仿照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遍历器风格的遍历方式的更多相关文章

  1. 添加登录装饰器的两种方式:FBV和CBV

    1.FBV方式:添加验证装饰器 def auth(func): def deco(request, *args, **kwargs): u = request.get_signed_cookie('u ...

  2. Swift快速给Cocoa库内置类添加便捷初始化器

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Cocoa中的NSShadow类默认没有我们需要的实例方法,为 ...

  3. Qt自定义类添加qvector报错

    PtsData& PtsData::operator=(const PtsData& obj){ return *this;} PtsData::~PtsData(){ }

  4. 遍历器Iterator--指针对象

    一. 什么是遍历器 1. 遍历器对象(Iterator) 遍历器对象本质上是一个指针对象,该对象有一个next方法,调用next方法返回一个 含有value和done属性的对象{value: val/ ...

  5. Iterator(遍历器) 和 for...of 循环

    是generator的前置知识 generator :https://www.cnblogs.com/wangtong111/p/11322961.html 遍历器(Iterator)就是这样一种机制 ...

  6. 疑问:Iterator 遍历器和数据集合各种遍历方法的区别

    https://es6.ruanyifeng.com/#docs/iterator Iterator(遍历器)的概念 Iterator 接口主要供for...of消费 Iterator 的遍历过程是: ...

  7. <JVM中篇:字节码与类的加载篇>04-再谈类的加载器

    笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...

  8. runtime-给系统已有类添加属性

    在没有接触runtime之前,我们接触到的能给类进行扩展的方法有类目(category)和延展(extension)两种.类目(category)可以给系统已有类添加扩展方法但是不能添加属性,并且被添 ...

  9. spring boot自定义类配置绑定在配置文件中自动提示

    在spring boot的日常使用中,我们可能需要使用配置绑定的方式动态配置自定义类的成员变量. 这个时候,我们在配置文件中配置spring默认已有的配置时,只需要输入部分关键字即可自动提示,如下图: ...

随机推荐

  1. 关于PHP程序员技术职业生涯规划

    看到很多PHP程序员职业规划的文章,都是直接上来就提Linux.PHP.MySQL.Nginx.Redis.Memcache.jQuery这些,然后就直接上手搭环境.做项目,中级就是学习各种PHP框架 ...

  2. 5分钟教你学会Django系统错误监控

    一.监控所有的request请求 如何实现系统监控,自动发送错误日志的邮件呢? 只需配置配置settings文件即可. 1.设置发送邮件配置信息 邮件会发送到ADMINS设定的邮件列表中. SERVE ...

  3. 创建一个Scalar-valued Function函数来实现LastIndexOf

    昨天有帮助网友解决的个字符串截取的问题,<截取字符串中最后一个中文词语(MS SQL)>http://www.cnblogs.com/insus/p/7883606.html 虽然实现了, ...

  4. [转]Web 通信 之 长连接、长轮询(long polling)

    本篇文章转载自Web 通信之长连接.长轮询(longpolling),版权归作者所有. 转者按:随着技术的发展,在HTML5中,可以通过WebSocket技术来完成长连接的开发,虽然如此,本文依然存在 ...

  5. TensorFlow框架下的RNN实践小结

    截至目前,TensorFlow的RNN APIs还处于Draft阶段.不过据官方解释,RNN的相关API已经出现在Tutorials里了,大幅度的改动应该是不大可能,现在入手TF的RNN APIs风险 ...

  6. 来不及说什么了,Python 运维开发剁手价仅剩最后 2 天

    51reboot 运维开发又双叒叕的搞活动了—— Python 运维开发 18 天训练营课程, 剁手价1299 最后2天 上课方式:网络直播/面授(仅限北京) DAY1 - DAY4 Python3 ...

  7. vue开发小结(下)

    前言 继前几天总结了vue开发小结(上)后,发现还有很多的点没有能列举出来,于是还是打算新建一个下篇,再补充一些vue开发中需要注意的细节,确实还是都是细节的问题,我只是在这里强调下,希望对大家有帮助 ...

  8. Effective C++学习笔记之explicit

    关键字: explicit意思为“明确的”和“清楚的”,是C++的关键词,意在阻止隐式类型的转换: 使用原因: 有时候不合法的隐式转换,会让乖巧听话的程序变得不可控.所以适当地使用explicit关键 ...

  9. 对于ps基本操作的归纳

    1.开始新的制作 1)新建 快捷键:Ctrl+n      格式:宽高根据要求自选:颜色模式常用R(红)G(绿)B(蓝) 2)打开电脑上的图片 快捷键:Ctrl+o 2.选框工具 快捷键:M 作用:能 ...

  10. Hexo+Github搭建博客问题

    搭建过程如下:   http://www.cnblogs.com/fengxiongZz/p/7707568.html   问题:第6步,发布上传代码一直不成功(没异常,也没成功).   解决:修改_ ...