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

时间:2012-12-26 18:53:17

标签: c++ data-structures map compiler-errors typedef

我正在尝试按键访问地图数据结构的元素,但是收到了编译错误。我使用typedef定义了我的地图数据结构,以简化地图实例化的语法。如您所见,密钥的类型为string,数据为自定义GameComponent个对象:

typedef map<string, GameComponent*> ComponentMap;
typedef map<string, GameComponent*>::iterator ComponentMapIter;
typedef map<string, GameComponent*>::const_iterator ComponentMapCIter;

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

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"]);
}

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

/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

3 个答案:

答案 0 :(得分:6)

由于operator[]中的std::map不是const,因此您无法在const方法中使用它(当然,在成员上)。

使用at(C ++ 11)或find&amp;迭代器预先C ++ 11。

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

答案 1 :(得分:6)

似乎m_components属于ComponentMap*类型。 当您编写m_components["Armor"]编译器时,将其解释为"Armor"的{​​{1}}动态数组元素的访问权限,这是没有任何意义的。

你想要的是ComponentMap。这将调用(*m_components)["some string"]的{​​{1}},但正如Luchian Grigore和Olaf Dietsche所提到的,operator[]没有const过载,所以这也会失败。剩下的唯一选择是使用ComponentMap

简化版将是:

std::map::operator[]

此代码与原始示例的行为不同,如果find没有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"元素,则会失败。 我们可以得到的最接近的是显式处理缺少元素,如果使用C ++ 11,则返回"Weapon""Attributes"

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

0

答案 2 :(得分:2)

getArmor()getWeapon()getAttributes()定义为const,但m_components[] 可能会修改m_components。因此,您必须先定义方法const或使用std::map::find

Armor* Character::getArmor() const
{
    auto i = m_components->find("Armor");
    if (i != m_components->end())
        return static_cast<Armor*>(i->second);

    return nullptr;
}