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 это пользовательский класс
Ключ должен быть типа foo*
, Так что вам нужно написать это:
mymap[&fa] = 1.0;
mymap[&fb] = 2.0;
Но помни это если fa
а также fb
являются локальными объектами, тогда они будут уничтожены, когда вы вернетесь из функции. Так что не стоит возвращаться mymap
из функции, так как объекты, используемые в качестве ключей, не существуют, как только функция возвращается.
Здесь не нужно ничего делать. Ваша карта ожидает указатели на 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.
Сохранение и использование указателя на некоторые локальные объекты внутри карты может быть 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));
}