Как я могу использовать структуру в качестве ключа в std :: map? - PullRequest
21 голосов
/ 26 августа 2011

У меня есть следующий код, но я получаю сообщение об ошибке в последней строке:

struct coord { 
    int x, y; 

    bool operator=(const coord &o) {
        return x == o.x && y == o.y;
    }

    bool operator<(const coord &o) {
        return x < o.x || (x == o.x && y < o.y);
    }
};

map<coord, int> m;
pair<coord, int> p((coord{0,0}),123);
m.insert(p); // ERROR here

Как я могу использовать структуру в качестве ключа на карте?


Я пытался изменить код на это:

struct coord { 
    int x, y; 

    bool const operator==(const coord &o) {
        return x == o.x && y == o.y;
    }

    bool const operator<(const coord &o) {
        return x < o.x || (x == o.x && y < o.y);
    }
};

Но я все еще получаю следующую ошибку:

C: \ Users \ tomc \ Desktop \ g> mingw32-make g ++ test.cpp -std = c ++ 0x В файле, включенном из c: \ mingw \ bin ../ lib / gcc / mingw32 / 4.5.2 / include / c ++ / string: 5 0: 0, из c: \mingw \ bin ../ lib / gcc / mingw32 / 4.5.2 / include / c ++ / bits / loc ale_classes.h: 42, из c: \ mingw \ bin ../ lib / gcc / mingw32 / 4.5.2 / include/ c ++ / bits / ios _base.h: 43, из c: \ mingw \ bin ../ lib / gcc / mingw32 / 4.5.2 / include / c ++ / ios: 43, из c: \ mingw \ bin ../lib / gcc / mingw32 / 4.5.2 / include / c ++ / ostream: 40, из c: \ mingw \ bin ../ lib / gcc / mingw32 / 4.5.2 / include / c ++ / iostream: 40, из test.cpp: 1: c: \ mingw \ bin ../ lib / gcc / mingw32 / 4.5.2 / include / c ++ / bits / stl_function.h: в функции-члене 'bool std :: less <_Tp> :: operator () (const _Tp &, const _Tp &) const [с _ Tp = координировать] ': c: \ mingw \ bin ../ lib / gcc / mingw32 / 4.5.2 / includede / c ++ / bits / stl_tree.h: 1184: 4: экземпляр защищен от 'std :: pair, bool> std :: _ Rb_tree <_Key, _Val, _KeyOfValue, _Compare, _Alloc> :: _ M_insert_unique (const _Val &) [с _Key= координировать, _Val = std :: pair, _KeyOfValue = std :: _ Select1st>, _Compare = std :: less, _Alloc = std :: allocator>] 'c: \ mingw \ bin ../ lib / gcc / mingw32 / 4.5.2 / include / c ++ / bits / stl_map.h: 501: 41: установлено из 'std :: pair, std :: _ Select1st>, _Compare, имя_папки _Alloc :: rebind :: value_type> :: other> :: iterator, bool> std :: map <_Key, _Tp, _Compare, _Alloc> :: insert (const std :: map <_Key, _Tp, _Compare, _ Alloc> :: value_type &) [с _Key = координировать, _Tp = int, _Compare= std :: less, _Alloc = std :: allocator>, имя типа std :: _ Rb_tree <_ Key, std :: pair, std :: _ Select1st>, _ Compare, имя типа _Alloc :: rebind :: value_ty pe> :: other> :: iterator = std :: _ Rb_tree_iterator>, st d :: map <_Key, _Tp, _Compare, _Alloc> :: value_type = std :: pair] 'test.cpp: 56: 12: создается здесь c: \ mingw\ bin ../ lib / gcc / mingw32 / 4.5.2 / include / c ++ / bits / stl_function.h: 230: 22: er ror:передача 'constordin' в качестве 'this' аргумента 'const boolordin :: operator <(co -st координировать &)' отбрасывает квалификаторы mingw32-make: *** [game] Ошибка 1 </p>

Ответы [ 4 ]

40 голосов
/ 26 августа 2011

Попробуйте и сделайте operator < const:

bool operator<(const coord &o)  const {

(ваши = operator, вероятно, должны быть == operator и const также)

8 голосов
/ 06 апреля 2012

Самым простым является определение глобального оператора "меньше чем" для вашей структуры вместо функции-члена.

std :: map использует - по умолчанию - функтор «lessthan», который, в свою очередь, использует глобальный «оператор <», определенный для типа ключа карты. </p>

bool operator<(const coord& l, const coord& r) {
     return (l.x<r.x || (l.x==r.x && l.y<r.y));
}
1 голос
/ 06 декабря 2011

Другое решение, которое может использоваться для сторонних типов данных, заключается в передаче Comparison object в качестве третьего параметра шаблона. пример

0 голосов
/ 28 февраля 2019

Как уже упоминалось в ответе от Andrii , вы можете предоставить пользовательский объект сравнения для map вместо определения operator< для своей структуры. Поскольку C ++ 11 , вы также можете использовать лямбда-выражение вместо определения объекта сравнения. Более того, вам не нужно определять operator== для вашей структуры, чтобы map работал. В результате вы можете сделать вашу структуру такой короткой, как эта:

struct coord {
    int x, y;
};

А остальная часть вашего кода может быть написана следующим образом:

auto comp = [](const coord& c1, const coord& c2){
    return c1.x < c2.x || (c1.x == c2.x && c1.y < c2.y);
};
std::map<coord, int, decltype(comp)> m(comp);

Код на Ideone

...