2

マップ データ構造の要素にキーでアクセスしようとしていますが、コンパイル エラーが発生します。マップのインスタンス化の構文を簡素化するために、typedef を使用してマップ データ構造を定義しました。ご覧のとおり、キーは型stringで、データはカスタムGameComponentオブジェクトです。

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

の派生クラスでGameComponent、マップに格納されている一意の GameComponent オブジェクトごとに標準の Composite パターン メソッドとアクセサーを作成しています。ただし、配列添字演算子を使用してアクセサー内のオブジェクトにアクセスすると、コンパイラ エラーが発生します。

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
4

3 に答える 3

6

operator[]in a std::mapis notであるため、メソッド内で (もちろんメンバーに対して)const使用することはできません。const

at(C++11) または C++11 よりfind前の & イテレータを使用します。

関連: std::map に const アクセサがないのはなぜですか?

于 2012-12-26T18:55:31.937 に答える
6

m_componentsタイプのようComponentMap*です。あなたが書くとき、コンパイラはそれを s の動的配列の -th 要素m_components["Armor"]へのアクセスとして解釈しますが、これは意味がありません。"Armor"ComponentMap

あなたが欲しいのはです(*m_components)["some string"]。これはoperator[]ofを呼び出しますComponentMapが、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;
}
于 2012-12-26T19:04:17.470 に答える
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;
}
于 2012-12-26T18:56:03.153 に答える