3

我试图确定一个对象是否已经包含在std::set. 根据 msdn (和其他来源),如果 set::find 函数end()没有找到您要求的元素,它应该返回。

但是,当我实现如下代码时,会改为set::find返回 junk ( )。0xbaadf00d

set<Cell*> cellSet;

Cell* cell = new Cell();    

if (cellSet.find(cell) == cellSet.end())
{
    ...
}

我正确使用它吗?我正在使用 Visual C++ 2005。

4

5 回答 5

10

您发布的代码将始终执行 , 中的代码if,并且0xbaadf00d 实现的“one-past-the-end”标记。

于 2009-05-04T16:48:18.480 回答
5

使用 stl set 时,我喜欢使用count函数来确定成员资格。我认为这使代码更易于阅读。

set<Cell*> cellSet;

Cell* cell = new Cell();    

if (cellSet.count(cell) == 0)
{
    ...
}
于 2009-05-04T17:12:43.460 回答
1

callSet.end() 也有值 0xbaadf00d 吗?

编辑

我在 VS2008 中运行了这个示例代码,一切都按预期工作。find 函数返回一个指向原始值的迭代器。

你到底看到了什么行为?它是返回 end() 还是返回集合中的另一个位置?

于 2009-05-04T16:45:06.537 回答
0

一个简单的错误是您应该测试不等于结束。

set<Cell*> cellSet;
Cell* cell = new Cell();
if (cellSet.find(cell) != cellSet.end())     // Test NOT EQUAL to end
{
     // Found item in set.
}

但是您还应该注意,您不是在比较实际的 Cell 值,而是比较指向 Cell 对象的指针(这可能是您想要的,也可能不是您想要的)。通常在 C++ 中,您不倾向于将指针存储在容器中,因为指针没有隐含的所有权,但有时可以。

要实际比较对象,您需要使用 find_if() 并传递谓词(函子)。

struct PointerCellTest
{
    Cell&  m_lhs;
    PointerCellTest(Cell* lhs): m_lhs(lhs) {}
    bool operator()(Cell* rhs)
    {
         return lhs.<PLOP> == rhs.<PLOP>
    }
};


if(find_if(cellSet.begin(),cellSet.end(),PointerCellTest(cell)) != cellSet.end())
{
     // Found item in set.
}
于 2009-05-04T17:23:12.247 回答
0

尝试仅编译和运行提供的代码片段,我保证您会发现它可以毫无问题地执行。这个问题几乎可以肯定是由于程序中其他地方发生的内存分配错误,例如引用未初始化的指针或指向已deleted 对象的指针。

你熟悉 C++ 容器如何管理它们的对象吗?他们不会为您删除指针。在可能的情况下,使用对象容器而不是指向对象的指针总是更安全。(在某些情况下,指针容器是必要的——尤其是当您希望容器存储来自单个类层次结构的不同类型的对象时。)

于 2009-05-04T16:57:53.510 回答