来自 std::map returns 的 find() 函数尽管没有有效的键值
The find() function from std::map returns a value despite not having a valid key
背景:
我想使用 std::pair
和 std::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:
我有这个简单的程序:
- 有两个
enums
-
- 各州,
- 一个用于转换,
与map
一起使用。
map
中的key
是一个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;
}
令人惊讶的是,这 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
。
背景:
我想使用 std::pair
和 std::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:
我有这个简单的程序:
- 有两个
enums
-- 各州,
- 一个用于转换,
与
map
一起使用。map
中的key
是一个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;
}
令人惊讶的是,这 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
。