为仿照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. 【Codeforces 848C】Goodbye Souvenir

    Codeforces 848 C 题意:给\(n\)个数,\(m\)个询问,每一个询问有以下类型: 1 p x:将第p位改成x. 2 l r:求出\([l,r]\)区间中每一个出现的数的最后一次出现位 ...

  2. ingress-nginx 添加https证书

    1.配了一个证书,发现报错: kubectl logs  ingress-nginx-controller-96fnv   -n ingress-nginx unexpected error vali ...

  3. Zephyr的Time、Timer、sleep

    正如Linux下一样,关于时间的系统函数可以分为三类:时间值.睡眠一段时间以及延迟执行. 在Zephyr上对应是什么样子呢?带着这个疑问,去了解一下这些函数. 以及他们与suspend之间的关系? 是 ...

  4. 大话设计模式(C#)

    还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 问个问题: 如何写出高质量的代码?灵活,可扩展,易读,易维护,可重构,可复用. ...

  5. Nginx+Tomcat+Memcached部署

    环境清单列表:(因为只有三台电脑,所有把Nginx和memcached放到一起) 应用服务器1:192.168.51.10: 应用服务器2:192.168.55.110: memcached服务器:1 ...

  6. C_数据结构_递归自己调用自己

    # include <stdio.h> void f(int n) { ) printf("哈哈\n"); else f(n-i); } int main(void) ...

  7. jenkins 上命令各种找不到问题

    代码: 兵马未动,粮草先行 作者: 传说中的汽水枪 如有错误,请留言指正,欢迎一起探讨. 转载请注明出处.   在使用jenkins的时候,会使用一些命令行,有的时候明明在电脑的命令行(终端)可以执行 ...

  8. FMDB数据库升级

    FMDBMigrationManager 是与FMDB结合使用的一个第三方,可以记录数据库版本号并对数据库进行数据库升级等操作.首先要集成FMDB和FMDBMigrationManager,建议使用c ...

  9. [2017BUAA软工]第零次博客作业

    第一部分:结缘计算机 1. 你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢?(必答) 当年高考前在专业这件事上纠结了好久,因为我对于大学各个专业具体学什么都不甚了解,于是就迟迟没有明确的目 ...

  10. MySQLi面向对象实践--insert、update、delete

    执行insert <?php $mysqli = new Mysqli(); $mysqli->connect("localhost","root" ...