代码之家  ›  专栏  ›  技术社区  ›  Duck Dodgers

std::map中的find()函数返回一个值,尽管没有有效的键[重复]

  •  0
  • Duck Dodgers  · 技术社区  · 5 年前

    背景: 我想用 std::pair std::map .

    文件上说:

    根据文件 map::find 我们知道:

    返回值

    对键等于键的元素的迭代器。如果没有这样的元素 找到,返回超过end(请参见end())的迭代器。

    思想/逻辑 :

    我有一个简单的程序:

    • 用两 enums -
      • 一份给美国,还有,
      • 一个用于过渡,
    • 与一起使用 map .

    • 这个 key 地图 是一个 STD:配对 . 这个 pair 由初始状态和转换组成。

    • find 适用于上述 钥匙 ,我们可以得到下一个状态。

    代码 :

    代码如下:

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

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

    这个 0 代表 State_Undefined 我想。这是令人惊讶的。因为哈希表中没有未定义的状态,所以我期望出现错误或警告,所以初始化了它。

    注:

    我知道,我应该检查迭代器 main() 这样的功能,就可以避免这种情况。

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

    问题 :

    但是,我就是不明白,为什么 find()->second 可以返回 A.K.a枚举 未定义状态 . 我从未将该值放入哈希表中。

    2 回复  |  直到 5 年前
        1
  •  2
  •   Matthieu Brucher    5 年前

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

    在这种情况下,它只是随机返回0。可能是-1。或者撞车。或者别的什么。

        2
  •  2
  •   eerorika    5 年前

    这是令人惊讶的。因为哈希表中没有未定义的状态,所以我期望出现错误或警告,所以初始化了它。

    在结束迭代器之后进行间接寻址的行为是未定义的。期望某些特定的行为会被误导。

    但是,我无法理解find()->second如何或为什么可以返回0 a.k.a枚举状态“未定义”。我从未将该值放入哈希表中。

    行为未定义。任何事情都可能发生。


    如果希望在元素不存在时出现异常,可以使用 map::at 而不是 map::find .