简体   繁体   中英

Use of find vs. at in map / unordered_map

The following shows two ways of looking up an element of an unordered_map , and raising some error condition if the element of the desired key does not exist. They essentially do the same thing. Is there reason to prefer one over the other, or is it simply a matter of style?

void foo()
{
    unordered_map<string, int> lookup;

    // Method 1. Lookup using find.
    const auto i = lookup.find("myKey");
    if (i == lookup.end()) {
        // Some error condition...
    }
    else {
        // Do something with i...
    }

    // Method 2. Lookup using try / catch.
    try {
        const auto& ele = lookup.at("myKey");
        // Do something with ele...
    }
    catch (out_of_range& e) {
        // Some error condition...
    }
}

Personally I would never use exceptions for something like that. Exceptions are for the truly exceptional. Their power lies in allowing you to write code without constant local error checking. But not finding an element in a container is not (usually) an error, its just one of two possibilities.

As a rule I would say use exceptions if not finding the element means you have to abort the entire function/operation/subsystem. Don't use it to check individual statement results.

These methods have completely different return values, thus they are useful in different situations.

For example, if you need the value itself, you may use both of them, as you may easily obtain the value from the iterator. But you cannot do the opposite: at returns a value reference, which cannot be "converted" to an iterator for O(1) time. The only way to "get" iterator from value reference is to iterate over the map using ie find . So if you need a value, call at , and if you need an iterator, call find . Also at should be faster as it does not handle intermediate iterator object and does not require dereference operator call.

Another concern is exception availability. Exceptions may be forbidden by the project's code style for some reason, or even disabled by compiler flags. In this case using find is the only option.

As exception handling imply restrictions to the optimizer, the second method results - in most cases - to larger binaries. In addition, exception handling is not desired (even disabled) on/in some systems.

In case you are developing a library potentially to be used by others, prefer the first method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM