std::map problems

This topic is 4176 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi, I am not sure why the following code is not working since I pretty much have used it perfectly well in the past. All I did was change the variable names and the typedef for the map.
[source lang = "cpp"]
struct GridIntersections
{
Real x;
Real y;
};

typedef std::map< Entity*, unsigned short > MAP_ENTITY2SHORT;
typedef std::map< GridIntersections, MAP_ENTITY2SHORT* > MAP_GRID2ENTITYS;

MAP_GRID2ENTITYS::iterator Grid::GetSector(GridIntersections sector)
{
MAP_GRID2ENTITYS::iterator itor = mSectors.end();
if ( (itor = mSectors.find(sector)) != mSectors.end() )
{
//return itor;
}
//return NULL;
return 0;
}


Edit: I forgot to put in the errors and I never knew I hit submit. Also the error is occuring on this line: if ( (itor = mSectors.find(sector)) != mSectors.end() ) And the errors: C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139): error C2784: 'bool std::operator <(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'const GridIntersections' C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139): error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const GridIntersections' C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139): error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Ax> &' from 'const GridIntersections' C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\string(148) : see declaration of 'std::operator<'' C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139): error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const T1 *' from 'const GridIntersections' C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139): error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Ax> &' from 'const GridIntersections' C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139): error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const GridIntersections' C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139): error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const GridIntersections' C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(139): error C2676: binary '<' : 'const GridIntersections' does not define this operator or a conversion to a type acceptable to the predefined operator [Edited by - Fruny on September 13, 2006 8:53:26 PM]

Share on other sites
define not working. I would think it wouldn't compile because NULL is not a valid MAP_GRID2ENTITYS::iterator. It's expecting an actual iterator to be returned, not a pointer.

Also why do you do this:
MAP_GRID2ENTITYS::iterator itor = mSectors.end();
and then reset the value of itor in the if statement.... it would read more clearly thusly:

MAP_GRID2ENTITYS::iterator itor = mSectors.find(sector);if ( itor != mSectors.end() ){    return itor;}return itor;

and actually the best way to write the function would be:
MAP_ENTITY2SHORT *Grid::GetSector(GridIntersections sector){    MAP_GRID2ENTITYS::iterator itor = mSectors.find(sector);    if ( itor != mSectors.end() )    {        return (*itor).second;    }    return NULL;}

-me

Share on other sites
The common practice for iterators would be to return mSectors.end() when the iterator cannot be found. Returning 0 or NULL like that is most likely why MSVC is crapping out on you. Though you can never really be sure with MSVC, its not the best C++ compiler.

Share on other sites
Thanks for the reply, I never knew I submitted the post so I have edited it. The error occurs on this line: if ( (itor = mSectors.find(sector)) != mSectors.end() )
and if its commented out it works perfectly. Yes that is a better way of writing it, and I will change it to that. However I want to return the initiator so I can modify the data, since this will be multi purpose. It will also create a record later on if one doesnt exist (for now it'll return null).

Share on other sites
Even though the error is fixed by removing the line, the error could still be the fact that you're returning 0. Templates are very weird creatures.

Try returning .end() instead of 0 and see if the error goes away.

Share on other sites
If you just want to return the iterator but not allow the user to have direct access to the mSectors map do this:

bool Grid::GetSector(GridIntersections sector, MAP_GRID2ENTITYS::iterator &retVal){    retVal = mSectors.find(sector);    if ( retVal != mSectors.end() )    {        return true;    }    return false;}`

a word of caution. It's not a good idea to pass around iterators to STL containers because various operations on the containers can invalidate the iterator. If you invalidate an iterator that someone else is holding and they subsequently use it, it can cause hard to find program crashes or memory stomps.

The point of your object seems to be to encapsulate the functionality of the mSectors map. As such, you really shouldn't be handing out direct control over that map to the outside world.

Because you're storing pointers in your mSectors map, returning the pointer is a perfectly valid way to allow outsiders to manipulate the data without harassing your map.

-me

Share on other sites
Ok, I guess I am am now going to return a pointer to the other map MAP_ENTITY2SHORT, considering the bugs that my way could potentially cause (I really dont want hard to find bugs, if it can be helped).
I have tried to return mSectors.end() and it is still causing an error.

The code is now:

MAP_ENTITY2SHORT *Grid::GetSector(GridIntersections sector)
{
MAP_GRID2ENTITYS::iterator itor = mSectors.find(sector);
if ( itor != mSectors.end() )
{
return (*itor).second;
}
//return NULL;
return mSectors.end()
}

Share on other sites
Did you define an operator<() that works on GridIntersections objects?

Share on other sites
Quote:
 Original post by FrunyDid you define an operator<() that works on GridIntersections objects?