Question

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!

Was it helpful?

Solution

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->());
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top