【问题标题】:Nested unordered_map has no member named ‘emplace’嵌套的 unordered_map 没有名为“emplace”的成员
【发布时间】:2017-04-14 13:53:50
【问题描述】:

我试图为我修复从 gamedev 书中获得的相当困难的程序。我认为它崩溃了,因为作者使用的是 Windows,而我使用的是 Linux (g++)。简而言之,我有几个类来执行应用程序状态的逻辑,并且我有映射映射来保存状态及其回调:

enum class StateType {
    Intro = 1, MainMenu, Game, Paused, GameOver, Credits
};

using Bindings  = std::unordered_map<std::string, Binding*>;
using CallbackContainer = std::unordered_map<std::string, std::function<void(EventDetails*)>>;
using Callbacks = std::unordered_map<StateType, CallbackContainer>;

class EventManager {
public:
...
    template<class T>
    bool AddCallback(StateType l_state, const std::string& l_name, 
        void(T::*l_func)(EventDetails*), T* l_instance) {
        auto itr = m_callbacks.emplace(l_state, CallbackContainer()).first;
        auto temp = std::bind(l_func, l_instance, std::placeholders::_1);
        return itr->second.emplace(l_name, temp).second;
    }

private:
    Callbacks m_callbacks;

我不确定要在此处包含我的代码的哪些部分。无论如何,我得到了一个糟糕的堆栈跟踪:

/usr/include/c++/5/bits/hashtable_policy.h: In instantiation of ‘struct std::__detail::__is_noexcept_hash<StateType, std::hash<StateType> >’:
/usr/include/c++/5/type_traits:137:12:   required from ‘struct std::__and_<std::__is_fast_hash<std::hash<StateType> >, std::__detail::__is_noexcept_hash<StateType, std::hash<StateType> > >’
/usr/include/c++/5/type_traits:148:38:   required from ‘struct std::__not_<std::__and_<std::__is_fast_hash<std::hash<StateType> >, std::__detail::__is_noexcept_hash<StateType, std::hash<StateType> > > >’
/usr/include/c++/5/bits/unordered_map.h:100:66:   required from ‘class std::unordered_map<StateType, std::function<BaseState*()> >’
/home/xxx/Projects/mushrooom/BaseState.h:48:28:   required from here
/usr/include/c++/5/bits/hashtable_policy.h:85:34: error: no match for call to ‘(const std::hash<StateType>) (const StateType&)’
  noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
...
/usr/include/c++/5/bits/unordered_map.h:649:7: error: ‘value’ is not a member of ‘std::__not_<std::__and_<std::__is_fast_hash<std::hash<StateType> >, std::__detail::__is_noexcept_hash<StateType, std::hash<StateType> > > >’
       equal_range(const key_type& __x) const
...
/home/xxx/Projects/mushrooom/EventManager.h: In member function ‘bool EventManager::AddCallback(StateType, const string&, void (T::*)(EventDetails*), T*)’:
/home/xxx/Projects/mushrooom/EventManager.h:93:32: error: ‘using Callbacks = class std::unordered_map<StateType, std::unordered_map<std::basic_string<char>, std::function<void(EventDetails*)> > > {aka class std::unordered_map<StateType, std::unordered_map<std::basic_string<char>, std::function<void(EventDetails*)> > >}’ has no member named ‘emplace’
         auto itr = m_callbacks.emplace(l_state, CallbackContainer()).first;

Callbacks 好像没有成员 emplace,但它是 std::unordered_map 并且有这样的方法。

g++-5, linux

【问题讨论】:

  • 如果我定义了EventDetailsBinding 类型,添加缺少的标准头包含并用}; 完成EventManger 的声明我可以让这个例子编译得很好。您需要提供minimal reproducible example 以获得有意义的答案。

标签: c++ c++11


【解决方案1】:

与emplace无关——是缺失的哈希函数!

您正在使用 std::unordered_map,换句话说就是哈希映射。如果你想使用一个对象作为键,这个对象必须提供一个可以计算哈希值的函数。

您现在有两个选择:

  1. 为您的类提供 std::hash 的模板特化或将自己的类作为第三个(哈希)模板参数传递给 std::unordered_map
  2. 改用 std::map - 这是一个不需要散列函数的树形图。

【讨论】:

  • 天哪,非常感谢,我选择了第二种方式,堆栈跟踪现在缩短了十倍!
猜你喜欢
  • 2015-11-14
  • 2013-03-26
  • 1970-01-01
  • 1970-01-01
  • 2014-12-14
  • 2015-05-23
  • 2014-11-09
  • 2015-06-09
相关资源
最近更新 更多