来自 std::map returns 的 find() 函数尽管没有有效的键值

The find() function from std::map returns a value despite not having a valid key

背景: 我想使用 std::pairstd::map.

创建状态图

文档说:

根据 map::find 的文档,我们知道:

Return value

Iterator to an element with key equivalent to key. If no such element is found, past-the-end (see end()) iterator is returned.

Idea/Logic:

我有这个简单的程序:

代码:

代码如下:

#include <utility>
#include <map>
#include <iostream>

typedef enum {
    State_Undefined = 0,
    State_NotConnected = 1,
    State_Transporting = 2,
    State_TransportFinished = 3,
    State_TransportStopped = 4
} State;
typedef enum {
    Transition_Undefined = 0,
    Transition_StopTransport = 1,
    Transition_StartTransport = 2,
    Transition_FinishTransport = 3
} Transition;

typedef std::pair<const State, const Transition> InitStateAndTransition;
typedef std::map<InitStateAndTransition, State> NextStateFromCurrentStateAndTransition;

NextStateFromCurrentStateAndTransition myMap = {
    {{State_NotConnected, Transition_StartTransport}, State_Transporting},
    {{State_Transporting, Transition_StopTransport}, State_TransportStopped},
    {{State_TransportStopped, Transition_FinishTransport}, State_TransportFinished},
    {{State_TransportStopped, Transition_StartTransport}, State_Transporting}
};

int main()
{
    State currentState = State_NotConnected;

    Transition testInput = Transition_StartTransport;
    State nextState = myMap.find(InitStateAndTransition(currentState, testInput))->second;
    std::cout << nextState << std::endl;

    testInput= Transition_StartTransport;
    nextState = myMap.find(InitStateAndTransition(nextState, testInput))->second;
    std::cout << nextState << std::endl;
    return 0;
}

令人惊讶的是,这 return 是输出,

2

0

0代表State_Undefined,我猜。这令人惊讶。我预料到会出现错误或警告,因为散列 table 中没有 State_Undefined,所以我进行了初始化。

注:

我明白了,我应该这样检查main()函数中的迭代器,这样就可以避免这种情况了。

    if (myMap.end() == myMap.find(InitStateAndTransition(nextState, testInput))) {
        return -1;
    }

问题

但是,我就是不明白,find()->second 怎么或为什么可以 return 一个 0 a.k.a 枚举 State_Undefined。我从来没有把这个值放在散列 table.

错误是您没有检查 find 的结果。如果返回的迭代器等于 end(),那么取消引用它是未定义的行为。

在这种情况下,它只是随机返回0。它可能是-1。或者崩溃。或者其他。

This is surprising. I had expected an error or a warning, since there is no State_Undefined in the hash table, I initialized.

间接尾后迭代器的行为未定义。期望某些特定行为会被误导。

But, I just can not understand, how or why the find()->second can return a 0 a.k.a the enum State_Undefined. I never put that value in the hash table.

行为未定义。什么事都有可能发生。


如果想在元素不存在时异常,可以用map::at代替map::find