Определение того, находится ли объект в std::set

StackOverflow https://stackoverflow.com/questions/820859

  •  03-07-2019
  •  | 
  •  

Вопрос

Я пытаюсь определить, содержится ли объект уже в std::set.Согласно msdn (и другим источникам), функция set::find должна возвращать end() если он не найдет элемент, который вы просили.

Однако, когда я реализую код, подобный следующему, set::find возвращает мусор (0xbaadf00d) вместо этого.

set<Cell*> cellSet;

Cell* cell = new Cell();    

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

Правильно ли я это использую?Я работаю в Visual C ++ 2005.

Это было полезно?

Решение

Ваш опубликованный код всегда будет выполнять код внутри if , а 0xbaadf00d равно «реализации одного шага» конец & Quot; маркер.

Другие советы

При использовании stl set мне нравится использовать функцию count для определения членства. Я думаю, что это облегчает чтение кода.

set<Cell*> cellSet;

Cell* cell = new Cell();    

if (cellSet.count(cell) == 0)
{
    ...
}

Имеет ли callSet.end() также значение 0xbaadf00d?

Редактировать

Я запустил этот пример кода в VS2008, и все сработало, как ожидалось.Функция find вернула итератор, указывающий на исходное значение.

Какое именно поведение вы наблюдаете?Возвращает ли он end() или возвращает другое место в наборе?

Попробуйте скомпилировать и запустить просто предоставленный вами фрагмент кода, и я гарантирую, что вы обнаружите, что он выполняется без проблем. Эта проблема почти наверняка связана с ошибками выделения памяти, возникающими в других местах вашей программы, такими как ссылка на неинициализированный указатель или указатель на объект, который был delete d.

Вы знакомы с тем, как контейнеры C ++ управляют своими объектами? Они не удаляют указатели для вас. Всегда безопаснее использовать контейнеры объектов, а не указатели на объекты, когда это возможно. (Существуют случаи, когда необходимы контейнеры указателей, в частности, когда вы хотите, чтобы контейнер сохранял объекты разных типов из единой иерархии классов.)

Одна простая ошибка заключается в том, что вы должны проверять, чтобы не было конца.

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

Но также вы должны заметить, что вы сравниваете не фактические значения ячейки, а указатель на объекты ячейки (которые могут быть, а могут и не совпадать с вашими). Обычно в 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.
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top