std :: hash专门用于我自己的类,并在类中使用它

Azi*_*ias 5 c++ c++11

我定义一个类Foo,并希望有一个以std::unordered_set<Foo>参数类型为参数的公共成员函数 。

为了能够使用std::unordered_set<Foo>,我必须专门std::hash<Foo> 研究std命名空间。

如果我不尝试std::unordered_set<Foo>Foo成员函数中用作参数类型,那没关系。

但是,一旦要std::unordered_set<Foo>Foo成员函数中用作参数类型,就很难定义专门化了 std::hash<Foo>。如果我在Foo声明后执行此操作,则声明时会出错,Foo因为std::hash<Foo>未定义。它std::hash<Foo>以前是一个移动定义,因为现在Foo未知,所以也不起作用。Foo在这种情况下,向前声明无效。

任何想法如何解决这个问题?

这是此类的示例

class Foo
{
public:
  std::unordered_set<Foo>::iterator findClosest(std::unordered_set<Foo> const &others)
  {
    return std::end(others);
  }

  size_t hashValue() const {
    return std::hash<int>()(m_Member);
  }

private:
  int m_Member;
};

namespace std
{
  template <>
  struct hash<Foo>
  {
    size_t operator()(Foo const & bar) const
    {
      return bar.hashValue();
    }
  };
}
Run Code Online (Sandbox Code Playgroud)

使用下面的答案,这是我最终使用的代码(由于存在dll,我需要放置一些MY_EXPORT_MACRO):

在文件Foo.h中

class Foo;

namespace std
{
  template <>
  struct MY_EXPORT_MACRO hash<Foo>
  {
    size_t operator()(Foo const &bar) const;
  };
}

class MY_EXPORT_MACRO Foo
{
public:
  Foo const *findClosest(std::unordered_set<Foo> const &others);

  size_t hashValue() const
  {
    return std::hash<int>()(m_Member);
  }

  bool operator==(const platypus::Segment2D &other) const
  {
    return m_Member == other.m_Member;
  }

private:
  int m_Member;
};
Run Code Online (Sandbox Code Playgroud)

在文件Foo.cpp中

size_t std::hash<Foo>::operator()(Foo const &bar) const
{
  return bar.hashValue();
}

Foo const *Foo::findClosest(std::unordered_set<Foo> const &others)
{
  Foo const *closest = nullptr;
  std::unordered_set<Foo>::const_iterator closestIt =
    std::min_element(std::begin(others), std::end(others), [this](Foo const &lhs, Foo const &rhs) {
      return std::abs(this->m_Member - lhs.m_Member) < std::abs(this->m_Member - rhs.m_Member);
    });

  if (closestIt != std::end(others))
  {
    closest = &(*closestIt);
  }

  return closest;
}
Run Code Online (Sandbox Code Playgroud)

Man*_*lva -1

std如果您愿意,可以尝试以下方法,而不是在命名空间中专门化模板。

#include <iostream>
#include <unordered_set>
struct FooHash;
class Foo {
    public:
    Foo(){
    }
    ~Foo(){
    }
    friend FooHash;
    private:
    std::string m_str;
};
struct FooHash
{
    std::size_t operator()(Foo const& f) const noexcept{
        return std::hash<std::string>{}(f.m_str);
    }
};
int main(){
    std::unordered_set<Foo,FooHash> fSet;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Live Code