Using VS 2008, the target environment is Windows CE with an ARM processor if that makes a difference. I know that the compiler we are using is kind of dated as well...
The basic problem I am having is that I am trying to make my own iterator for a map wrapper I wrote and overloading the operator->() is giving me trouble. This is the bit of code that is giving me issues:
const pair<wstring, PropertyMap*>* ObjectMapIterator::operator->() const
{
return &*m_MapIter;
}
I know that it doesn't really make sense to return a const variable usually, but I can't seem to figure out how to do this in a way that lets the rest of the program be const-correct without doing that.
The error I get is this:
error C2440: 'return' : cannot convert from 'const std::pair<_Ty1,_Ty2> *' to 'const std::pair<_Ty1,_Ty2> *'
The header for this iterator looks like this:
class ObjectMapIterator
{
public:
ObjectMapIterator(const ObjectMap& rObjectMap);
const ObjectMapIterator& operator++(int rhs);
std::pair<std::wstring, PropertyMap*> operator*() const;
const std::pair<std::wstring, PropertyMap*>* operator->() const;
bool isDone() const;
private:
const std::map<std::wstring, PropertyMap*>* m_pPropertyMaps;
std::map<std::wstring, PropertyMap*>::const_iterator m_MapIter;
};
As you can see, both the m_MapIter and the return value of the overloaded operator are the same... I took all of the const statements out of the .h and .cpp files for this part of the project and recompiled with the same error, so I don't think this is an issue with that.
If I do something like this instead, the program will compile:
const pair<wstring, PropertyMap*>* ObjectMapIterator::operator->() const
{
const pair<wstring, PropertyMap*>* returnVal = new pair<wstring, PropertyMap*>(*m_MapIter);
return returnVal;
}
I know that doing that would lead to a memory leak, I didn't put it into a smart pointer just to save space for posting this.
Here is the whole .cpp file in case you might find that relevant:
#include "stdafx.h"
#include "ObjectMap.h"
using namespace std;
ObjectMapIterator::ObjectMapIterator(const ObjectMap& rObjectMap)
:m_pPropertyMaps(&(rObjectMap.m_PropertyMaps)),
m_MapIter(m_pPropertyMaps->begin())
{}
const ObjectMapIterator& ObjectMapIterator::operator++(int rhs)
{
if(m_MapIter != m_pPropertyMaps->end())
{
m_MapIter++;
return *this;
}
else
{
return *this;
}
}
pair<wstring, PropertyMap*> ObjectMapIterator::operator*() const
{
return *m_MapIter;
}
const pair<wstring, PropertyMap*>* ObjectMapIterator::operator->() const
{
return &*m_MapIter;
}
bool ObjectMapIterator::isDone() const
{
return m_MapIter == m_pPropertyMaps->end();
}
The ObjectMapIterator definition is inside of the ObjectMap.h file. So I am not forgetting to include ObjectMapIterator.
I've been scratching my head over this for too long. Please let me know if you figure anything out. Thanks!
std::map::const_iterator
returns a temporary, not a reference, so you are trying to take address of that temporary and return it.
Why not simply return pair
by value?
std::pair<std::wstring, PropertyMap*>* ObjectMapIterator::operator->() const
{
return *m_MapIter;
}
Actually, if your operator will return std::map::const_iterator::pointer
, as
std::map::const_iterator::operator->()
does, everything will be ok:
std::map<std::wstring, PropertyMap*>::const_iterator::pointer operator->() const
{
return &*m_MapIter;
}
Also, as far as value, returned by std::map::const_iterator::operator->()
is implementation defined, may be it would be better to use
auto operator->() const -> decltype(m_MapIter.operator->())
{
return (m_MapIter.operator->());
}