C++ 特定领域的C++;迭代器方法

C++ 特定领域的C++;迭代器方法,c++,iterator,C++,Iterator,除了迭代器概念所要求的正常方法之外,还有什么理由不在迭代器中包含非标准方法吗?其他方法将特定于迭代器生成的项的类型 具体例子 为了使我的问题更具体,我在GUI菜单中对菜单项进行交互。迭代器在内部通过索引访问菜单。取消引用时,它在该索引处查询菜单项,创建一个表示菜单返回的属性的不可变对象,并在返回对该对象的引用之前将其缓存在成员变量中 不安全解决方案 另一种方法是使表示可变,并将属性更新写回基础菜单。它看起来像这样: menu m = some_menu(); menu_iterator pos

除了迭代器概念所要求的正常方法之外,还有什么理由不在迭代器中包含非标准方法吗?其他方法将特定于迭代器生成的项的类型


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

不安全解决方案 另一种方法是使表示可变,并将属性更新写回基础菜单。它看起来像这样:

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

menu_item i = *pos;
...
i.caption("foo");
i.disable();
这意味着每个
菜单项
表示必须存储其位置和菜单句柄——这没什么大不了的——除非菜单在创建项表示后插入/删除了项。在这种情况下,当一个完全不同的项目的属性发生变化时,各种各样的地狱可能会爆发

menu m = some_menu();
menu_iterator pos = m.begin()+3;
...
pos.caption("foo");
pos.disable();
更好的解决方案? 所以我的想法是添加额外的方法来更改迭代器的属性,而不是它返回的值。这样,用户总是知道正在更新的是当前指向的项,而使其无效的插入的惯用迭代器语义也适用(它不会真正使其无效,它只会指向不同的项)


你觉得怎么样?

以下是我要做的:

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

我不会将
caption()
之类的方法放在迭代器本身中。(例如,如何将它们与每个一起使用?)

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

您在这方面有点失去了我。。。您的迭代器是否遵循任何标准迭代器语义?这听起来有点过早optimization@K-对不起,是的,正常的迭代器语义将保持不变。编辑为clarify@thehouse:只要您的迭代器遵守并满足已知迭代器类别之一的语义,您就可以添加任何您想要的额外方法/功能。@Cheersandhth.-Alf这不是优化问题,而是安全问题。如果我向调用者返回一个对象,他们可以很合理地预期,对它进行变异总是会变异概念上的“methoditem对象”,尽管他们获取了该对象。但是,如果菜单被扩展或截断,它将不会被扩展或截断。实际上没有底层菜单项对象,只有一个菜单句柄和一个整数。我真的不希望打电话的人知道底层菜单的方式。将项目称为代理似乎泄露了这只是一个包装器的事实。迭代器是visitor的一个特例?你确定?用什么方法?不,我不确定,我哪儿都没读过。但据我所知,访客是一个物体,它穿过某个更大结构的每一个元素,并在必要时采取行动。你的情况是相似的。类似的还有patternMatcher,它遍历一个字符串,直到匹配为止,然后你可以调用很多方法(获取匹配组、获取位置等)。如果它对您有帮助,只需将名称从迭代器更改为visitor、menuChanger或其他任何名称。如果它似乎适合你的需要,而且没有人提出有力的反对理由,那就试试吧