2012-12-26 70 views
2

编译错误我想通过键访问地图数据结构的元素,但得到一个编译器错误。我已经使用typedefs定义了我的地图数据结构,以简化地图实例化的语法。正如你所看到的,关键是string类型和数据是定制GameComponent对象:编译时尝试访问std :: map元素与运算符[]

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

在派生类中的GameComponent,我创造与存取中存储的每个独特的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 

回答

6

似乎m_componentsComponentMap*类型。 当您编写m_components["Armor"]时,编译器会将其解释为对的动态数组ComponentMap的第012个元素的访问,这没有任何意义。

你想要的是(*m_components)["some string"]。这将调用ComponentMapoperator[],但是Luchian Grigore和Olaf 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); 
} 

此代码不具有相同的行为,你的原来的例子,如果m_components没有"Armor""Weapon""Attributes"元素将失败。 最接近的我们可以得到的是明确处理元素缺失,并返回0nullptr如果您使用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; 
} 
+0

是的,这是我最终使用的那个。谢谢。 – dtg

6

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

使用at(C++ 11)或find &迭代器pre-C++ 11。

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

+0

谢谢!这正是我的问题 – liang

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

'auto'是一个C++ 11功能吗?它不会使用我的版本的GNU编译器,我认为它是C++ 11以前的版本... – dtg

+0

是的,'auto'是C++ 11的特性。 – Nekuromento

+0

@Dylan试试吧。它已经出现在'-std = C++ 0x'选项中。所以如果你有一个合理的当前gcc(至少gcc 4.6),它会起作用。 –

相关问题