使用指向值的原始指针从 std::list<Value> 中擦除?
Posted
技术标签:
【中文标题】使用指向值的原始指针从 std::list<Value> 中擦除?【英文标题】:Erasing from std::list<Value> using a raw pointer to Value? 【发布时间】:2013-03-18 00:44:10 【问题描述】:我有一个属于管理构造的std::list<Value>
,每当调用工厂方法时都会分发Value *
指针。当需要销毁Value
时,这些指针会传回给管理器。但是,我不确定如何最好地使用这些指针来查找和擦除/删除元素。
class ValueManager
public:
Value * createValue(ValueDef & def)
m_valueList.push_back( Value( def ) );
return &m_valueList.back();
void destroyValue(Value * target)
// Mystery!
// How does one remove/erase a list element
// with only a pointer to it's value?
private:
std::list<Value> m_valueList;
;
::erase
和 ::remove
似乎都不适合这项任务,一个采用迭代器而不是指针,而后者采用整个值,这是无法完成的,因为在这种情况下,没有可以接受==Values
之间的比较方法,只有指针才能可靠的找到目标。
我的问题是,destroyValue()
可以采取的最有效的实现是什么?
【问题讨论】:
您返回的地址属于 iterator,而不是值。使用迭代器 itself 作为返回值(除了真正的std::list<>
之外,不要尝试此操作)。
@WhozCraig - 不确定我是否遵循,它返回存储为列表中最后一个元素的元素的地址,对吧?是的,我使用的是列表,因为它不会重新分配节点,从而使内存地址无效。
您应该返回一个std::list<Value>::iterator
。在接收端使用它的语法与指针相同(*x
将使用迭代器的解引用运算符来获取底层值)。访问地址需要一点技巧(&(*x)
),但仍然可行。但是,现在您也可以将该迭代器用作包含 std::list<Value>
的基于迭代器的操作的直接输入,例如 erase()
等。
【参考方案1】:
简单:停止返回原始指针,并开始返回迭代器。然后想要销毁一个的用户将在它创建时收到的值传递,就像现在一样。并且取消引用仍然可以像使用原始指针一样工作。但是擦除也可以,而且效率很高。
【讨论】:
我想避免使用迭代器,因为它们在使用它的代码中需要冗长的std::list<Value>::iterator
声明。此外,它还公开了迭代器访问未显式返回的其他元素的能力,例如使用++
,如果使用的话,这将导致事情变得混乱。有没有办法只使用指针?
所以创建一个typedef,比如ValueIter
。这样,只需再输入 2 个字符(与 Value *
相比)。如果您确实需要防止“移动”返回的迭代器,只需创建自己的类类型并返回它,并让它包含一个迭代器并实现 operator*
以支持取消引用。以上是关于使用指向值的原始指针从 std::list<Value> 中擦除?的主要内容,如果未能解决你的问题,请参考以下文章
指向std :: vector和std :: list元素的指针
指向 std::vector 和 std::list 元素的指针
使用 std::initializer_list 创建指向 std::min 的函数指针
如何从 STL 列表中的迭代器访问指向结构的指针而不是其元素