背景:
我想使用std::pair
和std::map
创建一个状态图。
文档说:
根据map::find的文档,我们知道:
返回值
迭代到具有与key等效的key的元素。如果没有这样的元素 找到后,将返回过去(见end())迭代器。
想法/逻辑:
我有一个简单的程序:
enums
-
与map
一起使用。
key
中的map
是std::pair
。 pair
由初始状态和过渡组成。
在以上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
。我从来没有将该值放在哈希表中。
答案 0 :(得分:2)
错误是您没有检查find
的结果。如果返回的迭代器等于end()
,则取消引用它是未定义的行为。
在这种情况下,它只是随机返回0。它可能是-1。还是崩溃。还是其他。
答案 1 :(得分:2)
这令人惊讶。我曾预期会出现错误或警告,因为我初始化的哈希表中没有State_Undefined。
间接定义过去的迭代器的行为是不确定的。期望某些特定行为会被误导。
但是,我只是不明白,find()-> second如何或为什么可以返回枚举State_Undefined的0。我从来没有将该值放在哈希表中。
该行为是不确定的。任何事情都会发生。
如果您希望在元素不存在时发生异常,则可以使用map::at
代替map::find
。