2012-12-26 71 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),它會起作用。 –

相關問題