0

I have a map like this

map<int,pair<int,int>>diff;

I am using it like this

int temp;
    for(int i=0;i<n-1;i++)
    {
        for(int j=i+1;j<n;j++)
        {
            temp=v[j]-v[i];
            if(temp>0)
            {
                if(diff.find(temp)!=diff.end())
                {
                    pair<int,int> a=diff.find(temp);
                    if(a.second>j)
                    {
                        a.second=j;
                        a.first=i;
                    }
                }
                else
                {
                    map.insert({temp,{i,j}});
                }
            }
        }
    }    

where n is the size of vector v.

The error I am getting is

error: conversion from ‘std::map<int, std::pair<int, int> >::iterator {aka std::_Rb_tree_iterator<std::pair<const int, std::pair<int, int> > >}’ to non-scalar type ‘std::pair<int, int>’ requested

pair<int,int> a=diff.find(temp);

I looked online and I found that if element exists then map.find() returns to the position of element in the vector so in this it should return the pair to the element right?

What am I doing wrong?

Devang Mukherjee
  • 185
  • 1
  • 1
  • 11
  • Use [map::count](https://en.cppreference.com/w/cpp/container/map/count) and compare it `!= 0`. Also `std::unordered_map` is in almost all cases the kind of map you are looking for. – nada Oct 30 '20 at 11:06
  • @nada often people want ordered maps – Caleth Oct 30 '20 at 11:11
  • @Caleth In [most cases they don't](https://stackoverflow.com/questions/13799593/how-to-choose-between-map-and-unordered-map). – nada Oct 30 '20 at 11:30
  • Put simply an iterator to an object is not the same as the object itself, just as a pointer to an object is not the same as the object itself. In both cases you have to *dereference* the iterator/pointer to get the object. Failing to distinguish between references to objects and objects is one of the biggest beginner confusions it seems. – john Oct 30 '20 at 11:35
  • @nada that has **exactly nothing** to do with identifying whether the use of `diff` requires it be ordered. Fast is meaningless in the face of incorrect – Caleth Oct 30 '20 at 11:36
  • @Caleth I can't remember the last time I encountered a map which was actually required to be ordered. In my experience that's in maybe less than 5% of all map usages. But maybe I've just worked with unusual C++ sources. – nada Oct 30 '20 at 12:00

1 Answers1

2

The error message explains exactly what is wrong. You are trying to initialise a pair<int, int> with an decltype(diff)::iterator.

The simple fix is to dereference the result of find, or to use at

pair<int,int> a=diff.at(temp);

Note that this is a copy, not a reference, so the following actions are discarded.

A better fix is to use the iterator from the first find

auto it = diff.find(temp);
if(it!=diff.end())
{
    if(it->second>j)
    {
        it->second=j;
        it->first=i;
    }
}
else
{
    map.insert({temp,{i,j}});
}

Note that map::insert returns a useful value, and it doesn't overwrite existing values. You can simplify even further:

auto [it, unused] = map.insert({temp,{i,j}});
if (it->second < j)
{
    it->second=j;
    it->first=i;
}
Caleth
  • 52,200
  • 2
  • 44
  • 75