c++ - 使用“分组”元素迭代向量?
问题描述
考虑包装在同一个向量中的 4 种颜色的示例(设计的这一方面不能轻易更改 - 例如来自第三方):
std::vector rgb_colors = {1,1,1,2,2,2,3,3,3,4,4,4};
以下可以工作:
for (size_t ci = 0; ci + 2 < rgb_colors.size(); ci+=3) {
auto& red_component = rgb_colors[ci];
auto& green_component = rgb_colors[ci+1];
auto& blue_component = rgb_colors[ci+2];
//...
}
在真空中,这种方法足够“无辜”。但是,对于现代 c++/等,我通常会避开这种编码方法,因为它更脆弱/容易出错/冗余/等。现在更喜欢基于范围的 for 循环、迭代器等。
那么解决这个问题的更有表现力或优雅的方法是什么?
更新: 添加了关于“数据布局”不能轻易更改的注释。
解决方案
正如评论中提到的,创建一个struct
表示颜色的颜色,或者更确切地说使用可能与您用于图形的任何库一起提供的颜色,以便您可以正确地与之交互:
struct color {
int red, green, blue;
// Add members as you see fit
};
std::vector rgb_colors = {color{1,1,1}, color{2,2,2}, color{3,3,3}, color{4,4,4}};
// or
// std::vector<color> rgb_colors = {{1,1,1}, {2,2,2}, {3,3,3}, {4,4,4}};
for (auto& c : rgb_colors) {
auto& red_component = c.red;
auto& green_component = c.green;
auto& blue_component = c.blue;
//...
}
或者,较少关注具体示例,您可以使用范围/迭代器适配器,例如boost::adaptors::stride
:
#include <boost/range/adaptor/strided.hpp>
//...
for (auto& c : boost::adaptors::stride(rgb_colors, 3)) {
auto& red_component = (&c)[0];
auto& green_component = (&c)[1];
auto& blue_component = (&c)[2];
//...
}
这仍然(如在您的示例中)要求您确保向量的长度可被整除3
以避免 UB 并且元素std::vector
首先是连续数组的一部分(如提供的那样),以便指针算术(&c)[i]
具有定义明确的行为。
推荐阅读
- linux - 如何编写一个检查 bash 命令结果的函数
- python - python在excel文件中追加新数据
- java - 我想使用编辑文本或底部导航视图而不是搜索菜单 Android Studio 来搜索我的回收视图。帮我
- svn - 通过添加空修订来代替错过的修订来恢复 SVN 存储库数据
- python - Pandas 无法读取 Numbers 生成的 csv 文件?
- javascript - 用三个点替换溢出的字符串字符的问题
- flutter - Flutter - 如何使用可编辑元素实现延迟初始化的 DataTable 类似视图?
- android-studio - 如何在 android studio 中自由移动我的 Button 和 Edittext
- c# - System.IO.FileNotFoundException:'无法加载文件或程序集'System.Private.CoreLib
- javascript - 在多个级别过滤嵌套的对象数组并取回数组中的匹配对象