Вставить с объектом, как ключ не может скомпилировать? - PullRequest
2 голосов
/ 09 октября 2010

У меня проблемы с компиляцией.Я не понимаю ошибку, выдаваемую компилятором.Ниже приведен код, иллюстрирующий проблему.

#include <map>

using namespace std;

class Thing
{
public:
    Thing(int n):val(n) {}

    bool operator < (const Thing& rhs) const
    {
        return val < rhs.val;
    }

    int getVal() { return val; }

private:
    int val;
};


int main(int argc, char* argv[])
{
    std::map<Thing, int> mymap;
    Thing t1(1);
    Thing t2(10);
    Thing t3(5);

    mymap[t1] = 1; // OK

    mymap.insert(t1); // Compile error
}

Теперь сообщение об ошибке компилятора:

test.cpp: в функции 'int main (int, char **)': test.cpp: 34: ошибка: нет соответствующей функции для вызова 'std :: map, std :: allocator>> :: insert (Thing &)' /usr/include/c++/4.4/bits/stl_map.h:499: примечание: кандидаты: std :: pair, std :: _ Select1st>, _Compare, имя_папки _Alloc :: rebind> :: other> :: iterator, bool> std :: map <_Key, _Tp, _Compare, _Alloc> ::вставить (const std :: pair &) [с _Key = Thing, _Tp = int, _Compare = std :: less, _Alloc = std :: allocator>] /usr/include/c++/4.4/bits/stl_map.h:539:примечание: имя типа std :: _ Rb_tree <_Key, std :: pair, std :: _ Select1st>, _Compare, имя типа _Alloc :: rebind> :: other> :: iterator std :: map <_Key, _Tp, _Compare, _Alloc>:: insert (имя типа std :: _ Rb_tree <_Key, std :: pair, std :: _ Select1st>, _Compare, имя типа _Alloc :: rebind> :: other> :: iterator, const std :: pair &) [with _Key = Thing,_Tp = int, _Compare = std :: less, _Alloc = std :: allocator>]

Whна это значит?Есть ли другой метод или оператор, который мне нужно определить в Thing, чтобы он компилировался?

Ответы [ 3 ]

9 голосов
/ 09 октября 2010

Вам нужно mymap.insert(std::pair<Thing,int>(t1,x));, где x - это значение, которое вы хотите отобразить на t1.

3 голосов
/ 09 октября 2010

Вы не можете вставить ключ (объект Thing) сам по себе - map::insert (по крайней мере, на вашей карте) взять std::pair<Thing,int>, чтобы вы вставили значение int, индексированное по ключу Thing.

Однако - мне кажется, что вы действительно хотите использовать std::set<Thing>, поскольку у вашего объекта Thing есть своя собственная семантика упорядочения. Повторение инкапсулированного int val в качестве значения в карте с ключом Thing является избыточным и нарушает красивую инкапсуляцию, которую вы здесь имеете.

int main(int argc, char* argv[])
{
    std::set<Thing> myset;
    Thing t1(1);
    Thing t2(10);
    Thing t3(5);

    std::pair<std::set<Thing>::iterator, bool> result = myset.insert(t1);

    std::set<Thing>::iterator iter = myset.find(t1);
}
0 голосов
/ 09 октября 2010

std::map::insert ожидает, что вы передадите ей пару ключ-значение.

mymap.insert(std::pair<Thing, int>(t2, 10)); будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...