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默认已有的配置时,只需要输入部分关键字即可自动提示,如下图: ...
随机推荐
- 【Codeforces 1132D】Stressful Training
Codeforces 1132 D 题意:给\(n\)个电脑的电量和耗电速度,你可以买一个充电器,它的充电速度是每秒\(v\)单位,\(v\)你自己定.问最小的\(v\)能使得在\(k\)秒内每秒给某 ...
- exBSGS·BSGS-Senior/扩展的BSGS
\(\rm{0x01\quad Preface}\) \(emmm\)严格来讲,不应该被算到一个模板里面.因为在我看来模板是人构造出来的,但是这个算法应该是一个解决问题的\(process\)-更像是 ...
- Spark笔记-DataSet,DataFrame
DataSet:面向对象的,从JVM进行构建,或从其它格式进行转化 DataFrame:面向SQL查询,从多种数据源进行构建,或从其它格式进行转化 RDD DataSet DataFrame互转 1. ...
- JaxbUtil转json转XML工具类
json转换为XML工具类 package com.cxf.value; import org.springframework.util.StringUtils; import javax.xml.b ...
- SQL Server 中如何移动tempdb到新的位置
操作步骤:1.检查tempdb的逻辑名字和它的存在位置.可以使用下面语句: SELECT name, physical_name FROM sys.master_files WHERE databas ...
- 使用Win PE修改其他硬盘中的系统注册表
使用场景:原来装的机械硬盘系统盘为C盘,后来买了个SSD固态硬盘后,进入WinPE系统后,把原来的C盘整个复制到了固态硬盘,然后用BooticeX64.exe工具在UEFI启动中增加SSD固态硬盘中的 ...
- 【php增删改查实例】第十四节 - 用户管理模块(起步)
从这一节开始,开始着手开发部门管理模块. 之后的内容就在此基础上进行增加. 1.用户查询 在目录中建立一个user文件夹,作为我们用户管理的模块. 打开这个文件,新建一个userManage.html ...
- SAAS云平台搭建札记: (一) 浅论SAAS多租户自助云服务平台的产品、服务和订单
最近在做一个多租户的云SAAS软件自助服务平台,途中遇到很多问题,我会将一些心得.体会逐渐分享出来,和大家一起探讨.这是本系列的第一篇文章. 大家知道,要做一个全自助服务的SAAS云平台是比较复杂的, ...
- BJOI2019 题解
BJOI2019 题解 在更了在更了 P5319 [BJOI2019]奥术神杖 对\(V_i\)求个\(\ln\)变成了让平均数最大,显然套分数规划,然后ac自动机上面dp #include<b ...
- 基于vue2.0 +vuex+ element-ui后台管理系统:包括本地开发调试详细步骤
效果演示地址, github地址: demo演示: 1.About 此项目是 vue2.0 + element-ui + node+mongodb 构建的后台管理系统,所有的数据都是从 ...