首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >尝试使用operator[]访问std::map元素时出现编译器错误

尝试使用operator[]访问std::map元素时出现编译器错误
EN

Stack Overflow用户
提问于 2012-12-27 02:53:17
回答 3查看 2.5K关注 0票数 2

我试图通过键访问地图数据结构的元素,但得到了一个编译器错误。我使用typedefs定义了我的地图数据结构,以简化地图实例化的语法。如您所见,键的类型是string,数据是自定义的GameComponent对象:

代码语言:javascript
运行
复制
typedef map<string, GameComponent*> ComponentMap;
typedef map<string, GameComponent*>::iterator ComponentMapIter;
typedef map<string, GameComponent*>::const_iterator ComponentMapCIter;

GameComponent的派生类中,我为我的映射中存储的每个唯一的GameComponent对象创建了标准的复合模式方法和访问器。但是,使用数组下标运算符访问访问器中的对象会导致编译器错误:

代码语言:javascript
运行
复制
void Character::add(const string& key, GameComponent* comp)
{
    m_components->insert( make_pair(key, comp) );
}

void Character::remove(const string& key)
{
    m_components->erase(key);
}

Armor* Character::getArmor() const
{
    // ERROR:
    return static_cast<Armor*>(m_components["Armor"]);
}

Weapon* Character::getWeapon() const
{
    // ERROR:
    return static_cast<Weapon*>(m_components["Weapon"]);
}

Attributes* Character::getAttributes() const
{
    // ERROR:
    return static_cast<Attributes*>(m_components["Attributes"]);
}

编译器错误的输出显示了一个“无效类型”错误,这让我摸不着头脑:

代码语言:javascript
运行
复制
/Users/Dylan/Desktop/RPG/character.cpp: In member function 'Armor* Character::getArmor() const':
/Users/Dylan/Desktop/RPG/character.cpp:66: error: invalid types 'ComponentMap* const[const char [6]]' for array subscript
/Users/Dylan/Desktop/RPG/character.cpp: In member function 'Weapon* Character::getWeapon() const':
/Users/Dylan/Desktop/RPG/character.cpp:71: error: invalid types 'ComponentMap* const[const char [7]]' for array subscript
/Users/Dylan/Desktop/RPG/character.cpp: In member function 'Attributes* Character::getAttributes() const':
/Users/Dylan/Desktop/RPG/character.cpp:76: error: invalid types 'ComponentMap* const[const char [11]]' for array subscript
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-27 03:04:17

看起来m_componentsComponentMap*类型的。在编写时,m_components["Armor"]编译器会将其解释为对"Armor"的动态数组的-th元素的访问,这没有任何意义。

你想要的是(*m_components)["some string"]。这将调用ComponentMapoperator[],但正如Luchian Grigore和Olaf Dietsche提到的那样,std::map::operator[]没有const重载,因此这也将失败。剩下的唯一选择就是使用find

简化版将是:

代码语言:javascript
运行
复制
Armor* Character::getArmor() const
{
    return static_cast<Armor*>(m_components->find("Armor")->second);
}

Weapon* Character::getWeapon() const
{
    return static_cast<Weapon*>(m_components->find("Weapon")->second);
}

Attributes* Character::getAttributes() const
{
    return static_cast<Attributes*>(m_components->find("Attributes")->second);
}

此代码与原始示例的行为不同,如果m_components没有"Armor""Weapon""Attributes"元素,则此代码将失败。我们能得到的最接近的方法是显式地处理元素的缺失,如果使用C++11,则返回0nullptr

最终正确的C++03兼容版本:

代码语言:javascript
运行
复制
Armor* Character::getArmor() const
{
    ComponentMapCIter i = m_components->find("Armor");
    if (i != m_components->end())
        return static_cast<Armor*>(i->second);
    return 0;
}

Weapon* Character::getWeapon() const
{
    ComponentMapCIter i = m_components->find("Weapon");
    if (i != m_components->end())
        return static_cast<Weapon*>(i->second);
    return 0;
}

Attributes* Character::getAttributes() const
{
    ComponentMapCIter i = m_components->find("Attributes");
    if (i != m_components->end())
        return static_cast<Attributes*>(i->second);
    return 0;
}
票数 6
EN

Stack Overflow用户

发布于 2012-12-27 02:55:32

因为std::map中的operator[]不是const,所以不能在const方法中使用它(当然是在成员上)。

在C++11之前使用at (C++11)或find &迭代器。

相关:Why does std::map not have a const accessor?

票数 6
EN

Stack Overflow用户

发布于 2012-12-27 02:56:03

getArmor()getWeapon()getAttributes()定义为const,但m_components[] 可能会修改m_components。所以你要么不能定义你的方法const,要么改用std::map::find

代码语言:javascript
运行
复制
Armor* Character::getArmor() const
{
    auto i = m_components->find("Armor");
    if (i != m_components->end())
        return static_cast<Armor*>(i->second);

    return nullptr;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14044862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档