特定于域的C ++迭代器方法

时间:2012-05-29 00:46:41

标签: c++ iterator

除了迭代器概念所需的常规方法之外,还有任何理由不在迭代器中包含非标准方法吗?其他方法将特定于迭代器生成的项目类型。


具体示例

为了使我的问题更具体,我正在GUI菜单中的菜单项进行交互。在内部,迭代器通过索引访问菜单。取消引用时,它在菜单中查询该项目,在该索引处创建一个不可变对象,表示菜单返回的属性,并在返回对它的引用之前将其缓存在成员变量中。

不安全的解决方案

另一种方法是使表示形式可变,并使其将属性更新写回底层菜单。它看起来像这样:

menu m = some_menu();
menu_iterator pos = m.begin() + 3;

menu_item i = *pos;
...
i.caption("foo");
i.disable();

这意味着每个menu_item表示必须存储其位置和菜单句柄 - 没什么大不了的 - 除非菜单已经插入/删除了项目,因为项目表示已创建。在这种情况下,当一个完全不同的项目的属性被改变时,各种地狱可能会破裂。

更好的解决方案?

所以我的想法是添加额外的方法,将属性更改为迭代器,而不是它返回的值。这样,用户总是意识到正在更新的是当前指向的项目,并且插入使其无效的通常迭代器语义适用(它不会真正使其无效,它只会指向不同的项目)。 p>

menu m = some_menu();
menu_iterator pos = m.begin()+3;
...
pos.caption("foo");
pos.disable();

您怎么看?

2 个答案:

答案 0 :(得分:1)

这就是我要做的事情:

  • 如果你不需要能够通过迭代器改变菜单项,只需使menu_item不可变 - 问题就解决了。
  • 如果您需要能够通过迭代器改变菜单项:
    • 如果您对底层菜单实现有这种类型的控制,请将menu_item指向实际菜单对象,该对象在添加新菜单项时不会失效。你可能甚至让迭代器在取消引用时返回(当然是通过引用)实际菜单对象,并完全取消menu_item包装器。
    • 如果您没有这种类型的控件,那么menu_item实际上是菜单项的代理,而不是菜单项本身。将其称为menu_item_proxy,并记录它具有代理行为,并且当迭代器失效时代理将失效。用户仍然可以使用语法pos->caption("foo")
    • 在“迭代器上”调用方法

我不会将像caption()这样的方法放在迭代器本身中。 (如何使用它们,比如for_each?)

答案 1 :(得分:-1)

向迭代器添加方法没有错。迭代器只是访客的一个特例。访客应该在访问某个对象时执行所有必需的操作。随意添加您的业务需要的任何方法