Что я могу использовать в качестве ключей std::map?
Я имею:
структура Coord { int row, col; оператор bool <(const Coord & other) const { строка возвратаЯ пытаюсь создать
map<Coord, Node*>
где вы можете посмотретьNode*
отCoord
,Проблема в том, что в ней есть ошибки. Поиски в
map<Coord, Node*>
отCoord
возвращают неправильные.Мне трудно понять, уместно ли это или нет.
Википедия говорит, что карта [ключи] требует строгого слабого порядка. Я сделал это неправильно? Есть ли способ заставить его работать, или ключи карты должны быть простыми значениями, которые можно "строго упорядочить"?
В основном вопрос в том, что требуется для кастома
struct
работать в качестве ключа для моей std::map?
5 ответов
Да, у вас вполне могут быть проблемы со строго-слабым порядком. Скорее всего, он не работает, как вы ожидаете. Рассматривать:
bool operator<( const Coord& other ) const
{
return row < other.row && col < other.col ;
}
obj1 (this) строка: 2 цв: 3
obj2 строка: 3 цв: 2
obj1
хорошо, тогда:
obj2
Единственный вывод заключается в том, что они должны быть равны (в зависимости от вашего оператора <). Поскольку это карта, а ключи уникальны, оба ключа находятся в одном месте. Такое поведение может или не может быть то, что вы ожидаете, но похоже, что это не так.
Вам нужно сделать приоритет между строкой / столбцом, чтобы <действительно работал так, как вы ожидаете:
bool operator<( const Coord& other ) const
{
// look at row first, if row is equal, check column.
if (row < other.row)
{
return true;
}
else if (row == other.row)
{
return col < other.col ;
}
return false;
}
Вы, вероятно, хотите:
bool operator<( const Coord& other ) const
{
if ( row < other.row ) {
return true;
}
else if ( row == other.row ) {
return col < other.col;
}
else {
return false ;
}
}
или наоборот. Этот тоже укусил меня несколько раз!
Попробуй это:
struct Coord
{
int row, col ;
bool operator<( const Coord& other ) const
{
if (row != other.row)
return row < other.row;
return col < other.col ;
}
} ;
bool operator<(const Coord& other) const
{
return row < other.row
|| row ==other.row
&& col < other.col;
}
Чтобы функция сравнения наложила строгий слабый порядок на набор значений для вашего объекта, одно из условий состоит в том, что эквивалентность должна быть транзитивной. a
а также b
называются эквивалентными, если (в синтаксисе C++) !(a < b) && !(b < a)
правда.
Ваш operator<
не соответствует этому требованию. Рассмотрим a = { 1, 3 }, b = { 3, 2 }, c = { 2, 1 }. В этом случае ни a Coord использоваться в качестве ключа в std::map
,