避免在常量成员函数和非常量成员函数中重复编写代码

3

我目前正在重构一个我很久以前创建的类。这个类是一种容器类型。

许多函数可以利用类结构,并因此实现为成员函数。然而,现在似乎有很多功能看起来“相同”,即“查找”函数:

iterator find(ITEM)
const_iterator find(ITEM) const;
iterator find_if(ITEM, PRED)
const_iterator find_if(ITEM, PRED) const;

有4个“函数”几乎描述了相同的内容(每个版本中代码几乎相同)。当更新类时,这变得非常繁琐,我必须确保每个版本都升级。有没有更好的方法来处理这些问题?该类中的其他一些函数可能需要2个谓词,这意味着我突然需要管理8个函数。

我尝试从常量版本调用“非常量版本”,但显然这样做是行不通的。

那么如何处理这些事情?只能硬着头皮写下来吗?

编辑:仅供参考:我的数据结构类似于“树”。每个“对象”包含数据(搜索查找的数据)和具有子树的“列表”。find函数在树的所有子树上递归工作(以及子子树)。-就像在搜索树时所期望的那样。

由于这种树没有清晰的“起始”或“结束”迭代器,因此使用std :: find无法得到正确的功能。


2
@FredOverflow:非常好的观点。迭代器和算法的存在正是为了解决OP想要自己重新实现的问题。 - Kerrek SB
1
@FredOverflow,Kerrek:不完全是这样。是的,std::find 存在,但 std::map::findstd::set::find 等也存在。 - Oliver Charlesworth
1
@OliCharlesworth:但没有 map::find_if :-) 是的,当适用时提供成员函数,但如果它只做与通用算法相同的事情,则不需要。 - Kerrek SB
@KerrekSB(和任何人)-好的,我解释了为什么我使用成员方法“find”。 (也许我应该重新命名它,但从类外看它非常合理)。 - paul23
我能理解为什么需要 member-find(本质上是重新实现了 std::set)。但我不明白为什么需要自定义的 find_if,也不明白为什么不能提供常规的迭代器接口,如 begin 和 end。 - Kerrek SB
每个容器都应该有begin()end()方法,无论其实现方式如何。std::set也是一棵树,并且具有这些方法,那么为什么你的树不能有呢? - fredoverflow
1个回答

8

Scott Meyers在Effective C++的第三项中解决了类似的问题,他通过在非const版本中调用const版本,然后将const结果强制转换回非const来解决问题:

const_iterator find(const T& value) const
{
    // actual implementation of find
}

iterator find(const T& value)
{
    return const_cast<iterator>(static_cast<const container*>(this)->find(value));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接