尽管没有有效的密钥,std :: map的find()函数仍返回一个值

时间:2019-01-07 17:24:05

标签: c++ enums hashtable stdmap std-pair

背景: 我想使用std::pairstd::map创建一个状态图。

文档说:

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

  

返回值

     

迭代到具有与key等效的key的元素。如果没有这样的元素   找到后,将返回过去(见end())迭代器。

想法/逻辑

我有一个简单的程序:

  • 带有两个enums-
    • 一个州,
    • 一个用于过渡,
  • map一起使用。

  • key中的mapstd::pairpair由初始状态和过渡组成。

  • 在以上find上应用key,我们可以获得下一个状态。

代码

代码如下:

#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;
}

令人惊讶的是,这将返回输出,

  

2

     

0

我猜0代表State_Undefined。这真是令人惊讶。我曾预期会出现错误或警告,因为我初始化的哈希表中没有State_Undefined。

注意:

我了解,我应该像这样检查main()函数中的迭代器,然后才能避免这种情况。

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

问题

但是,我只是不明白find()->second如何或为什么可以返回0枚举State_Undefined。我从来没有将该值放在哈希表中。

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

  

这令人惊讶。我曾预期会出现错误或警告,因为我初始化的哈希表中没有State_Undefined。

间接定义过去的迭代器的行为是不确定的。期望某些特定行为会被误导。

  

但是,我只是不明白,find()-> second如何或为什么可以返回枚举State_Undefined的0。我从来没有将该值放在哈希表中。

该行为是不确定的。任何事情都会发生。


如果您希望在元素不存在时发生异常,则可以使用map::at代替map::find