【问题标题】:dereferencing iterator causes 'can not convert' error when it seems it shouldn't取消引用迭代器会导致“无法转换”错误,而它似乎不应该
【发布时间】:2012-03-21 19:49:57
【问题描述】:

使用 VS 2008,目标环境是带有 ARM 处理器的 Windows CE,如果有区别的话。我知道我们使用的编译器也有点过时了......

我遇到的基本问题是我正在尝试为我编写的地图包装器创建自己的迭代器,并且重载 operator->() 给我带来了麻烦。这是给我带来问题的代码:

const pair<wstring, PropertyMap*>* ObjectMapIterator::operator->() const
{
    return &*m_MapIter;
}

我知道通常返回一个 const 变量并没有什么意义,但我似乎无法弄清楚如何以一种让程序的其余部分在不这样做的情况下保持 const 正确的方式做到这一点.

我得到的错误是这样的:

错误 C2440: 'return' : 无法从 'const 转换 std::pair<_ty1> *' 到 'const std::pair<_ty1> *'

此迭代器的标头如下所示:

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;
};

如您所见,m_MapIter 和重载运算符的返回值是相同的...我从项目的这一部分的 .h 和 .cpp 文件中取出所有 const 语句并重新编译同样的错误,所以我认为这不是问题。

如果我这样做,程序将编译:

const pair<wstring, PropertyMap*>* ObjectMapIterator::operator->() const
{
    const pair<wstring, PropertyMap*>* returnVal = new pair<wstring, PropertyMap*>(*m_MapIter);
    return returnVal;
}

我知道这样做会导致内存泄漏,我没有将它放入智能指针中只是为了节省发布空间。

这是整个 .cpp 文件,以防您发现相关内容:

#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();
}

ObjectMapIterator 定义位于 ObjectMap.h 文件中。所以我不会忘记包含 ObjectMapIterator。

我为这个问题挠头太久了。请让我知道,如果你想出任何办法。谢谢!

【问题讨论】:

    标签: c++ iterator const-iterator


    【解决方案1】:

    std::map::const_iterator 返回一个临时的,而不是一个引用,所以你正试图获取那个临时的地址并返回它。

    为什么不简单地按值返回pair

    std::pair<std::wstring, PropertyMap*>* ObjectMapIterator::operator->() const
    {
        return *m_MapIter;
    }
    

    实际上,如果您的运算符将返回std::map::const_iterator::pointer,则为 std::map::const_iterator::operator-&gt;() 会,一切都会好起来的:

    std::map<std::wstring, PropertyMap*>::const_iterator::pointer operator->() const
    {
    return &*m_MapIter;
    }
    

    另外,std::map::const_iterator::operator-&gt;() 返回的值是实现定义的,使用起来可能会更好

    auto operator->() const -> decltype(m_MapIter.operator->())
    {
    return (m_MapIter.operator->());
    }
    

    【讨论】:

    • 好点!我知道我现在哪里出错了,但这并不能完全解决我的问题。您必须为 operator-> 返回一个指针才能正常工作,因为 C++ 将采用类似“objMapIter->second”的语句并将其转换为“(objMapIter.operator->())->second”。但这肯定会帮助我找到一个有效的解决方案。谢谢!
    • 感谢您的提醒。你可能只是让我免于再花几个小时搜索信息。迭代器有时会令人困惑 O_o。
    猜你喜欢
    • 2020-12-21
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-03
    • 1970-01-01
    相关资源
    最近更新 更多