- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个方向枚举,其中包含 6 个方向条目(N、NE、SE、S、SW、NW),它们基本上是图中节点的边。我经常需要遍历所有邻居,目前仅使用 int 从 0->5 进行迭代。
有时还需要从例如迭代2->1 环绕,目前通过从 2->2+5 迭代并在使用时取模 6 来完成。
有什么我可以做的,可以在不损失性能的情况下使它更安全/更容易使用吗?具有固定整数范围的 for 循环可以展开、内联等。基于 vector 的方法不能(在枚举中使用静态常量 vector )
我已经在这样的方案中有了枚举:
struct Direction{
enum Type{
N, NE, ...
}
unsigned COUNT = ...;
Type t_;
operator Type(){return t_;}
Direction(Type t):t_(t){assert(N<=t<COUNT);}
explicit Direction(unsigned t):t_(t%COUNT){}
static Direction fromUInt(unsigned t){return Direction(Type(t));}
}
所以我想要的是拥有允许在整个集合上高效迭代的迭代器,并且还允许对任意起点进行迭代,在这种情况下迭代器环绕。
这个怎么写?我想不出任何东西,例如整个循环的 start=end 是无效的。或者我应该只使用 start=givenStartType、end=start+COUNT 并对每个迭代器取消引用取模吗?
不幸的是不允许使用 C++11
最佳答案
编辑以回应澄清
您在每次取消引用时对迭代器取模 COUNT
的想法是一个很好的想法。请参阅下面的反向迭代器/可迭代组合。在使用 -O3
编译 clang 后,我检查了程序集输出。编译器展开循环。输出为 2 1 0 5 4 3
。您可以实现前向迭代器,或将方向作为参数。您还可以通过枚举类型将其制作成模板。
不幸的是,从使用语法的角度来看,我不认为这比另一个所示的 do
-while
循环更能给你带来好处答案——至少在 C++11 之前不会。它确实隐藏了各种索引变量,并帮助您避免错误使用它们,但它更加冗长。
#include <iostream>
struct Direction {
enum Type {N, NE, SE, S, SW, NW};
static const unsigned COUNT = 6;
Type t_;
operator Type() { return t_; }
Direction(Type t) : t_(t) { }
explicit Direction(unsigned t) : t_(Type(t % COUNT)) { }
};
struct ReverseIterable {
const unsigned start_;
struct iterator {
unsigned offset_;
explicit iterator(unsigned offset) : offset_(offset) { }
Direction operator *() { return Direction(offset_); }
iterator& operator++() { --offset_; return *this; }
bool operator ==(const iterator &other)
{ return offset_ == other.offset_; }
bool operator !=(const iterator &other) { return !(*this == other); }
};
explicit ReverseIterable(Direction start) : start_(start) { }
iterator begin() { return iterator(start_ + Direction::COUNT); }
iterator end() { return iterator(start_); }
};
int main()
{
ReverseIterable range = ReverseIterable(Direction::SE);
for (ReverseIterable::iterator iterator = range.begin();
iterator != range.end(); ++iterator) {
std::cout << (int)*iterator << " ";
}
std::cout << std::endl;
return 0;
}
在 C++11 中,循环可以是:
for (Direction direction : ReverseIterable(Direction::SE))
std::cout << (int)direction << " ";
std::cout << std::endl;
您可能(ab?)使用宏在 C++98 中获得类似的东西。
我暂时保留了下面的原始答案,因为如果枚举定义可以更改,它会简化可维护性,并且因为它允许稀疏范围。可以在它之上实现一个非常相似的迭代器。
关注安全的原始答案
这对于您的目的来说可能完全是矫枉过正,并且它可能不适合我将在下面描述的原因。但是,您可以使用此库(免责声明:我是作者):https://github.com/aantron/better-enums编写这样的代码:
#include <iostream>
#include <enum.h>
ENUM(Direction, int, N, NE, SE, S, SW, NW)
int main()
{
size_t iterations = Direction::_size();
size_t index = 2;
for (size_t count = 0; count < iterations; ++count) {
std::cout << Direction::_values()[index] << " ";
index = (index + 1) % Direction::_size();
}
std::cout << std::endl;
return 0;
}
输出:
SE S SW NW N NE
(值是 int
大小的枚举,但被转换为字符串以仅输出到 std::cout
)。
这显示了对整个集合的迭代,起点是任意的。您可以使它向前或向后移动,并在任何枚举上对其进行模板化。
我认为在您的问题中使用模数是个好主意。这段代码只是给你一些关于枚举中常量数量的反射信息,并将它们放在一个数组中。
这可能不合适的原因是,由于您没有使用 C++11,数组 Direction::_values()
将在程序启动时初始化。我认为循环展开仍然会发生,但编译器将无法对数组的内容做任何事情。该数组仍将静态分配,但元素在编译期间将不可用。
如果您以后可以选择使用 C++11,数组将与静态初始化的 int[6]
基本相同(实际上,Direction[6]
,其中 Direction
是文字 struct
类型)。
(实际上,我想我可以公开一个 int
数组而不是 Direction
数组,即使在 C++98 中它也会被静态初始化)。
关于c++ - 迭代方向枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31819727/
如果您有超过 1 个具有相同类名的(动态)文本框,并使用 jquery 循环遍历每个所述文本框,您是否可以假设每次选择文本框的顺序都是相同的? 示例: 文本框 1 值 = 1文本框 2 值 = 2文本
有人知道为什么这段代码无法顺利运行吗?它似乎不喜欢使用yield关键字进行迭代:我正在尝试从任何级别的列表或字典中挖掘所有数字(对列表特别感兴趣)。在第二次迭代中,它找到 [2,3] 但无法依次打印
我关于从 mysql 数据库导出数据并将其保存到 Excel 文件(多表)的创建脚本。我需要让细胞动态基因化。该脚本正确地显示了标题,但数据集为空。当我“回显”$value 变量时,我检查了数据是否存
我正在尝试在 Python 中运行模拟,由此我绘制了一个数组的随机游走图,给定了两个变量参数的设定水平。 但是,我遇到了一个问题,我不确定如何迭代以便生成 250 个不同的随机数以插入公式。例如我已经
我是学习 jquery 的新手,所以如果这是一个相对简单的问题,我深表歉意。我有一个 ID 为 ChartstoDisplay 的 asp.net 复选框列表。我正在尝试创建 jquery 来根据是否
我正在尝试根据在任意数量的部分中所做的选择找出生成有效案例列表的最佳方法。也许它不是真正的算法,而只是关于如何有效迭代的建议,但对我来说这似乎是一个算法问题。如果我错了,请纠正我。实现实际上是在 Ja
如果我使用 sr1 为 www.google.com 发送 DNSQR,我会收到几个 DNSRR(s) 作为回复,例如(使用 ans[DNSRR].show() 完成): ###[ DNS Resou
假设有这样一个实体类 @Entity public class User { ... public Collection followers; ... } 假设用户有成千上万的用户关注者。我想分页..
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: Nested jQuery.each() - continue/break 这是我的代码: var steps =
我刚从 F# 开始,我想遍历字典,获取键和值。 所以在 C# 中,我会说: IDictionary resultSet = test.GetResults; foreach (DictionaryEn
我知道已经有很多关于如何迭代 ifstream 的答案,但没有一个真正帮助我找到解决方案。 我的问题是:我有一个包含多行数据的txt文件。 txt 文件的第一行告诉我其余数据是如何组成的。例如这是我的
我有 12 个情态动词。我想将每个模态的 .modal__content 高度与 viewport 高度 进行比较,并且如果特定模态 .modal__content 高度 vh addClass("c
在此JSFiddle (问题代码被注释掉)第一次单击空单元格会在隐藏输入中设置一个值,并将单元格的背景颜色设置为绿色。单击第二个空表格单元格会设置另一个隐藏输入的值,并将第二个单元格的背景颜色更改为红
这是一个非常具体的问题,我似乎找不到任何特别有帮助的内容。我有一个单链表(不是一个实现的链表,这是我能找到的全部),其中节点存储一个 Student 对象。每个 Student 对象都有变量,尽管我在
有没有办法迭代 IHTMLElementCollection? 比如 var e : IHTMLLinkElement; elementCollection:IHTMLElementCollect
我正在尝试用 Java 取得高分。基本上我想要一个 HashMap 来保存 double 值(因此索引从最高的 double 值开始,这样我更容易对高分进行排序),然后第二个值将是客户端对象,如下所示
我想在宏函数中运行 while/until 循环,并限制其最大迭代次数。我找到了如何在“通常”sas 中执行此操作: data dataset; do i=1 to 10 until(con
Iterator iterator = plugin.inreview.keySet().iterator(); while (iterator.hasNext()) { Player key
晚上好我有一个简单的问题,我警告你我是序言的新手。假设有三个相同大小的列表,每个列表仅包含 1、0 或 -1。我想验证对于所有 i,在三个列表的第 i 个元素中,只有一个非零。 此代码针对固定的 i
我在 scheme 中构建了一个递归函数,它将在某些输入上重复给定函数 f, n 次。 (define (recursive-repeated f n) (cond ((zero? n) iden
我是一名优秀的程序员,十分优秀!