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

dtg*_*dtg 2 c++ typedef compiler-errors map data-structures

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

typedef map<string, GameComponent*> ComponentMap;
typedef map<string, GameComponent*>::iterator ComponentMapIter;
typedef map<string, GameComponent*>::const_iterator ComponentMapCIter;
Run Code Online (Sandbox Code Playgroud)

在派生类中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"]);
}
Run Code Online (Sandbox Code Playgroud)

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

/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
Run Code Online (Sandbox Code Playgroud)

Luc*_*ore 6

因为operator[]在a std::mapconst,你不能在const方法中使用它(当然在成员上).

使用at(C++ 11)或find&iterators pre-C++ 11.

相关:为什么std :: map没有const访问器?


Nek*_*nto 6

它似乎m_components是类型ComponentMap*.当您编写m_components["Armor"]编译器解释时,作为s "Armor"的动态数组的-th元素的访问ComponentMap,这没有任何意义.

你想要的是什么(*m_components)["some string"].这将调用operator[]ComponentMap,但作为Luchian格里戈里和奥拉夫Dietsche提到,std::map::operator[]没有一个const超载,所以这将失败过.剩下的唯一选择是使用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);
}
Run Code Online (Sandbox Code Playgroud)

此代码不具有相同的行为,你的原来的例子,如果将失败m_components没有"Armor","Weapon""Attributes"元素.我们可以得到的最接近的是显式处理缺少元素和返回,0或者nullptr如果你使用C++ 11.

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

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;
}
Run Code Online (Sandbox Code Playgroud)