web-dev-qa-db-fra.com

Comment puis-je obtenir une valeur d'une carte?

J'ai un map nommé valueMap comme suit:

typedef std::map<std::string, std::string>MAP;
MAP valueMap;
...
// Entering data.

Ensuite, je passe cette carte à une fonction par référence:

void function(const MAP &map)
{
  std::string value = map["string"];
  // By doing so I am getting an error.
}

Comment puis-je obtenir la valeur de la carte, qui est passée en tant que référence à une fonction?

43
Aneesh Narayanan

Malheureusement, std::map::operator[] Est une fonction membre non-const et vous avez une référence const.

Vous devez soit changer la signature de function, soit faire:

MAP::const_iterator pos = map.find("string");
if (pos == map.end()) {
    //handle the error
} else {
    std::string value = pos->second;
    ...
}

operator[] Traite l'erreur en ajoutant une valeur construite par défaut à la carte et en lui renvoyant une référence. Cela ne sert à rien si tout ce que vous avez est une référence const, vous devrez donc faire quelque chose de différent.

Vous pouvez ignorez cette possibilité et écrivez string value = map.find("string")->second;, si la logique de votre programme vous garantit que "string" Est déjà une clé. Le problème évident est que si vous vous trompez, vous obtenez un comportement indéfini.

70
Steve Jessop

map.at ("key") lève une exception s'il manque une clé

Si k ne correspond à la clé d'aucun élément du conteneur, la fonction lève une exception out_of_range.

http://www.cplusplus.com/reference/map/map/at/

19
Gabe Rainbow

Le réponse par Steve Jessop explique bien pourquoi vous ne pouvez pas utiliser std::map::operator[] Sur un const std::map. Gabe Rainbow's réponse suggère une alternative intéressante. Je voudrais juste fournir un exemple de code sur la façon d'utiliser map::at() . Donc, voici un exemple amélioré de votre function():

void function(const MAP &map, const std::string &findMe) {
    try {
        const std::string& value = map.at(findMe);
        std::cout << "Value of key \"" << findMe.c_str() << "\": " << value.c_str() << std::endl;
        // TODO: Handle the element found.
    }
    catch (const std::out_of_range&) {
        std::cout << "Key \"" << findMe.c_str() << "\" not found" << std::endl;
        // TODO: Deal with the missing element.
    }
}

Et voici un exemple main() fonction:

int main() {
    MAP valueMap;
    valueMap["string"] = "abc";
    function(valueMap, "string");
    function(valueMap, "strong");
    return 0;
}

Sortie:

Valeur de la clé "chaîne": abc
Clé "forte" non trouvée

Code sur Ideone

0
honk

Comment puis-je obtenir la valeur de la carte, qui est passée en tant que référence à une fonction?

Eh bien, vous pouvez le passer comme référence. Le wrapper de référence standard c'est-à-dire.

typedef std::map<std::string, std::string> MAP;
// create your map reference type
using map_ref_t = std::reference_wrapper<MAP>;

// use it 
void function(map_ref_t map_r)
{
    // get to the map from inside the
    // std::reference_wrapper
    // see the alternatives behind that link
    MAP & the_map = map_r;
    // take the value from the map
    // by reference
    auto & value_r = the_map["key"];
    // change it, "in place"
    value_r = "new!";
}

Et le test.

    void test_ref_to_map() {

    MAP valueMap;
    valueMap["key"] = "value";
    // pass it by reference
    function(valueMap);
    // check that the value has changed
    assert( "new!" == valueMap["key"] );
}

Je pense que c'est gentil et simple. Prendre plaisir ...

0
Chef Gladiator