Оператор перегрузки [] для карты stl в стеке переполнения

class foo{

public:
int a, b, c;
double val;

foo(int a){
...
}

...
}

Теперь я хочу сделать:

map <foo*, double> mymap;

foo fa(2);
foo fb(4);

mymap[fa] = 1.0;
mymap[fb] = 2.0;

Очевидно, я получаю ошибку, что [] не определено для типа foo. Но как мне перегрузить этот оператор? И в этом отношении, как я могу получить указатель на foo? Потому что я предполагаю, что это не определено, так как foo это пользовательский класс

0

Решение

Ключ должен быть типа foo*, Так что вам нужно написать это:

mymap[&fa] = 1.0;
mymap[&fb] = 2.0;

Но помни это если fa а также fb являются локальными объектами, тогда они будут уничтожены, когда вы вернетесь из функции. Так что не стоит возвращаться mymap из функции, так как объекты, используемые в качестве ключей, не существуют, как только функция возвращается.

3

Другие решения

Здесь не нужно ничего делать. Ваша карта ожидает указатели на fooтак что вам нужно передать указатели на foo, Вы можете исправить свой код следующим образом:

mymap[&fa] = 1.0;
mymap[&fb] = 2.0;

берегись Вы должны быть абсолютно уверены, что foo объекты будут жить так же долго, как и карта, в противном случае последний будет иметь висячие указатели. Это, например, закончится слезами:

map <foo*, double> mymap;

{
foo fa(2);
foo fb(4);
mymap[&fa] = 1.0;
mymap[&fb] = 2.0;
} // fa and fb cease to exist

// state of mymap is messed up here.
1

Сохранение и использование указателя на некоторые локальные объекты внутри карты может быть extemely опасно. Прежде всего, вы можете разбить ваше приложение, разыменовав std::map ключ, когда объекты выходят из области видимости. Более того, его действительно сложно использовать, и в большинстве случаев это не то, что задумал программист. В твоем случае:

auto it = mymap.find(&foo(2))

не скомпилирует и:

foo fc(2);
auto it = mymap.find(&fc);

не найдет никакого значения внутри контейнера (fa имеют одинаковое значение, но другой указатель). Это действительно то, что вы хотели?

Вот почему я бы рекомендовал переопределить ваш std::map в std::map<foo, double> mymap; который будет хранить и сравнивать foo по значению. Чтобы это работало, вам нужно либо foo::operator<() или предоставить свой собственный алгоритм std::map в качестве аргумента шаблона. Первый случай будет выглядеть так:

class foo {
int a, b, c;
double val;
public:
foo(int a) {}
bool operator<(const foo &other) const
{ return a < other.a && b < other.b && c < other.c; }
};int main()
{
std::map<foo, double> mymap;

foo fa(2);
foo fb(4);

mymap[fa] = 1.0;
mymap[fb] = 2.0;

auto it = mymap.find(foo(2));
}
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector