【问题标题】:Specializing std::hash for private member class专用于私有成员类的 std::hash
【发布时间】:2014-06-04 22:34:30
【问题描述】:

我有一个类(称为Outer),它有一个私有成员类(Inner)。我想将Outer::Inner 的实例存储在无序的标准容器中,所以我想专门化std::hash<Outer::Inner>

但是,当写这个时:

namespace std {
    template<>
    struct hash<Outer::Inner> {
        std::size_t operator()(const Outer::Inner &arg) const
        {
            return std::hash<int>()(arg.someSpecialProperty);
        }
    };
}

编译器抱怨:

error: 'Inner' is a private member of 'Outer'
            std::size_t operator()(const Outer::Inner &p) const
                                                ^

我试图通过关注this answer 使std::hash 成为朋友结构,但这也不起作用:Outer::Inner 的前向声明失败:

error: use of undeclared identifier 'Outer'

那么我应该如何进行(如果我打算做的事情是可能的)?

【问题讨论】:

  • 通过参考这篇文章:stackoverflow.com/questions/8760181/… 看来你的情况是不可能的,因为你不能在 std::hash 中添加友谊......
  • @AntiClimacus 因为我不是声明原始std::hash 模板的人,对吧?
  • 这就是原因,是的。
  • @AntiClimacus 哦,谢谢。嗯,这很令人失望。 :-((如果您有这种感觉,请不要犹豫,写一个答案。)
  • 你不能在Outer里面声明friend struct std::hash&lt;Inner&gt;;吗? (可能在声明或定义Inner 之后。)然后定义你的专业。

标签: c++ c++11 hash unordered-set stdhash


【解决方案1】:

知道了!解决方案是使用您自己的仿函数,而不是专门化 std::hash。

struct A
{
  A() { v.insert(std::make_pair(B(1), 6)); }

private:
  struct B
  {
    B(int i = 0) : m_i(i) { }

    int m_i;
  };

  struct HashB { std::size_t operator()(const B& b) const { return b.m_i; } };
  struct EqualB { bool operator()(const B&b1, const B&b2) const { return b1.m_i == b2.m_i; } };


  std::unordered_map<B, int, HashB, EqualB> v;
};

【讨论】:

    【解决方案2】:

    由于它是私有内部类型,我假设您在封闭类中有一个 privateprotected std::unordered_map 成员。如果是这种情况,只需编写一个私有内部散列函子并将其作为std::unordered_map 的第三个参数传递。我认为这是解决问题的最简单方法。

    【讨论】:

    • 是的,我终于做到了。我猜这不是最漂亮的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2015-07-05
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多