是否可以在C++中使用转换迭代器?

Cyg*_*gon 5 c++ iterator updating conventions type-conversion

假设我有一个C++迭代器,它不仅遍历数据结构,而且在解除引用时也对元素应用转换.

作为一个真实的例子,这里有一个迭代器遍历位图中的像素,将位图特定的像素格式转换为方便的结构:

class ConstPixelIterator {

  public: struct Pixel {
    float Red;
    float Green;
    float Blue;
    float Alpha;
  };

  public: ConstPixelIterator(const Bitmap &bitmap);

  // ...standard iterator functionality...

  public: Pixel operator *() {
    // Read from memory and convert pixel format-specific bytes into Pixel structure
  }

};
Run Code Online (Sandbox Code Playgroud)

现在,如果我想实现一个非const迭代器(即让用户修改像素),那么最好的方法是什么?

我考虑过的一些想法:

  • 我可以在Pixel结构中放置访问器方法而不是普通字段,并为其所有者提供电话回家的参考.然而,这意味着如果用户改变了R,G,B和A,我会将像素转换为位图的像素格式4次并写入存储器4次.

  • 我可以从迭代器返回一个Pixel引用,并为它提供一个Update()在像素被更改时需要调用的方法.这将是非直观的并且冒着用户忘记打电话的风险Update.

  • 我总是可以返回Pixelby值并提供一个特殊的赋值运算符.是否打破标准迭代器模式 - 在没有解除引用的情况下分配给迭代器应该移动迭代器,而不是更新它指向的元素

MSa*_*ers 3

我们有一个现有的示例std::vector<bool>::iterator- 必须采用一些技巧才能写入单个位。

一种解决方案是返回ProxyPixel. 它保留对原始像素的引用。您说更新 R、G、B、A 可能会导致 4 次写入。这是事实,也是可以理解的。在第一次写入 R 后,底层图像毕竟应该具有更新的 R 值。

或者您乐意接受最终的更新吗?在这种情况下,您可以延迟写回ProxyPixel::~ProxyPixel. 是的,当代理像素发生变化时,底层图像将暂时不同步,但它会更有效。合理的权衡。

  • Eric Niebler 最近写了一篇内容非常丰富的[博客文章](http://ericniebler.com/2015/01/28/to-be-or-not-to-be-an-iterator/),关于代理迭代器的问题关于标准迭代器类别(只是将其添加为OP的仅供参考)。 (2认同)