【问题标题】:unordered_map of vectors resetting vectors向量的 unordered_map 重置向量
【发布时间】:2013-05-26 19:47:59
【问题描述】:

我正在尝试构建一个类来处理键回调。

为此,我有一个这样定义的地图:

class Keyboard {
public:
   void registerCallback(int key, callback_fn func, bool repeat = false);
   void onKeyEvent(int key, int state);

private:
    typedef std::function<void (int)> callback_fn;

    struct Callback {
        Callback(callback_fn f, bool r)
            : func(f), repeat(r), last_state(-1) {}

        callback_fn func;
        bool repeat;
        int last_state;
    };

    std::unordered_map<int, std::vector<Callback>> callbacks;
};

然后我像这样注册回调:

void Keyboard::registerCallback(int key, callback_fn func, bool repeat) {
    // My understanding is that if there is nothing mapped to the key
    // it will create a new vector. Otherwise it will return the mapped
    // object. I did try checking if anything already exists at the key
    // and if not creating a new vector but it yielded the same results.
    callbacks[key].push_back({ func, repeat });
}

但是我遇到了一个问题,即映射矢量似乎丢失了它的所有元素。

当我注册回调时,给定键处的向量会增加大小,但是当我尝试用另一种方法迭代向量时,它没有元素。

下面是我对向量进行迭代的方法。

void Keyboard::onKeyEvent(int key, int state) {
    for(auto& callback : callbacks[key]) {
        if(callback.repeat || callback.last_state != state) {
            callback.func(state); 
        }
    }
}

请注意,如果我将std::cout &lt;&lt; callbacks[key].size() &lt;&lt; std::endl; 添加到它会打印0 的函数顶部。

如果重要,这里是我如何注册回调的示例。

keyboard.registerCallback('w', [](int state) {
    std::cout << "w " << (state == GLFW_PRESS ? "pressed" : "released") << std::endl;
}, true);

我怀疑我的问题源于我更习惯的 Java 映射和 C++ 映射之间的差异

【问题讨论】:

  • 在 registerCallback 调用之后会打印什么:std::cout &lt;&lt; keyboard.callbacks['w'].size(); ?
  • 当您检索回调向量时,您确定使用与添加它们时相同的callbacks 实例吗?
  • 只有这些被调用的函数会修改callbacks吗?你确定你没有在某处创建和操作callbacks 的副本吗?
  • callbacks 只有一个实例,它都保存在一个 Singleton 类中,Keyboard 并且这些是唯一可以访问 callbacks 的函数 抱歉,上面没有说清楚,我已更新以尝试反映这一点。
  • 或者它是一个不同的密钥,或者它还没有注册。我建议如下:将std::cout &lt;&lt; "Registering " &lt;&lt; key &lt;&lt; std::endl; 放在registerCallback() 的开头,将std::cout &lt;&lt; "Looking up for " &lt;&lt; key &lt;&lt; std::endl; 放在onKeyEvent 的开头。您是否以正确的顺序和相同的数字键值看到输出? (为了 100% 确定我会在 Keyboard 对象的构造函数中添加一个 cout。)

标签: c++ map vector


【解决方案1】:

让我猜一下:问题是您收到的键码是大写字母('W';字母键码通常是大写的),但注册一个小写字母的回调('w')。

【讨论】:

    【解决方案2】:

    问题很可能是区分大小写的问题,因为您的代码没有什么特别之处,并且在调试器中运行 10 秒确认没有发生任何神奇的事情。只要您始终使用相同的“键盘”实例,那么它找不到您要查找的“键”的唯一原因是因为它与您注册的键不同。

    您是否在调试器中单步执行并确定要搜索的密钥?你试过输出吗?

    如果您必须处理可变大小写,那么您始终可以重载“unordered_map”以使用自定义散列函数,它可以为您进行无大小写比较。

    【讨论】:

      猜你喜欢
      • 2013-11-19
      • 1970-01-01
      • 2021-01-22
      • 1970-01-01
      • 2019-01-28
      • 2014-10-29
      • 1970-01-01
      • 2011-11-29
      • 2020-02-27
      相关资源
      最近更新 更多