如何避免实现 const 和非常量迭代器的代码重复?

2023-12-22

我正在实现一个具有类似 STL 接口的自定义容器。我必须提供一个常规迭代器和一个常量迭代器。这两个版本的迭代器的大部分代码是相同的。我怎样才能避免这种重复?

例如我的容器类是Foo,我正在实施FooIterator and FooConstIterator。两个迭代器都必须提供类似的方法operator++()它们是相同的。

我的问题类似于如何删除类似 const 和非常量成员函数之间的代码重复? https://stackoverflow.com/questions/123758/how-do-i-remove-code-duplication-between-similar-const-and-non-const-member-funct,但这个问题的答案特定于 const 和非常量方法,尤其是访问器。我不明白这如何推广到迭代器问题。

我应该有FooIterator从获得FooConstIterator并用额外的非常量方法扩展它?这要么导致虚拟方法,要么导致方法隐藏,这在这里似乎不合适。

Perhaps FooIterator应包含一个FooConstIterator。尽管该方法确实减少了实现重复,但它似乎重新引入了许多样板方法定义。

是否有聪明的模板技术可以从单个定义生成两个迭代器?或者也许有一种方法——令人震惊——使用预处理器来消除这些几乎相同的类。

我尝试查看本地 STL 实现,看看它是如何处理这个问题的。有太多的帮助器类,我在理解设计时遇到了麻烦,但看起来功能只是重复的。

在以前的项目中,我的自定义容器构建在标准 STL 容器之上,因此我不必提供自己的迭代器。在这种情况下,这不是一个选择。


我强烈推荐马特·奥斯汀 (Matt Austern) 撰写的多布博士期刊 (Dr. Dobb's Journal) 的原创文章,题为“标准图书馆员:定义迭代器和常量迭代器” http://www.drdobbs.com/the-standard-librarian-defining-iterato/184401331,2001 年 1 月。如果该链接出现问题,现在 Dr. Dobb's 已经停止运营,它也可以使用here http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/CUJ/2001/0101/austern/austern.htm.

为了防止这个替换答案被删除,我总结一下解决方案。

这个想法是将迭代器实现为一个带有额外模板参数的模板,该参数是一个布尔值,表示这是否是 const 版本。在实现中,const 和非 const 版本不同的任何地方,您都可以使用模板机制来选择正确的代码。马特·奥斯汀的机制被称为choose。它看起来像这样:

template <bool flag, class IsTrue, class IsFalse>
struct choose;

template <class IsTrue, class IsFalse>
struct choose<true, IsTrue, IsFalse> {
   typedef IsTrue type;
};

template <class IsTrue, class IsFalse>
struct choose<false, IsTrue, IsFalse> {
   typedef IsFalse type;
};

如果您对 const 和非常量迭代器有单独的实现,那么 const 实现将包括如下所示的 typedef:

typedef const T &reference;
typedef const T *pointer;

并且非常量实现将具有:

typedef T &reference;
typedef T *pointer;

但与choose,您可以有一个基于额外模板参数进行选择的实现:

typedef typename choose<is_const, const T &, T &>::type reference;
typedef typename choose<is_const, const T *, T *>::type pointer;

通过使用底层类型的 typedef,所有迭代器方法都可以具有相同的实现。参见马特·奥斯汀的完整的例子 http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/CUJ/2001/0101/austern/list1.htm.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何避免实现 const 和非常量迭代器的代码重复? 的相关文章

随机推荐