【问题标题】:Can I get (portable) access to the C++ standard library's hash implementation?我可以(便携式)访问 C++ 标准库的哈希实现吗?
【发布时间】:2016-02-21 06:53:22
【问题描述】:

GNU C++ 标准库有:

  struct _Hash_impl
  {
    static size_t
    hash(const void* __ptr, size_t __clength,
     size_t __seed = static_cast<size_t>(0xc70f6907UL))
    { return _Hash_bytes(__ptr, __clength, __seed); }
    /* etc. */
  }

作为其实现的一部分(例如,它用于字符串)。现在,我也想使用该代码...如何以可移植的方式访问它(例如,以一种可以与 clang 的 libc++ 一起使用的方式)?

【问题讨论】:

  • 您在寻找std::hash&lt;std::string&gt;吗? en.cppreference.com/w/cpp/utility/hash
  • @GManNickG:我必须为此构建一个字符串,不是吗? IIRC,您不能只将一堆字节包装在 std::string 中。
  • 啊,我明白你现在在说什么了。 std::hash 是您唯一可以访问标准哈希接口的方法,遗憾的是,它的指定不足。它没有用于组合散列的任何东西(例如,散列元组或数组)。如果你想要一些可移植的东西,包括范围的散列,Boost 有一个很好的散列库。
  • 或者,显然,只需复制该代码并将其称为您自己的哈希并管理您自己的库。 :)
  • @GManNickG:你对我下面的想法有什么看法?

标签: c++ hash portability c++-standard-library string-hashing


【解决方案1】:

否。您无法以可移植的方式访问编译器的内部实现细节。这怎么可能行得通?

您甚至无法确定在同一编译器供应商的下一次编译器更新后该实现是否仍然存在。或者更糟的是,它可能仍然可以正常编译,但具有不同的运行时行为。这是可维护性的噩梦,也是等待发生的无休止的调试会话。

如果您将来需要可移植性或向后兼容性,请实现自己的哈希函数并模仿_Hash_impl 的行为。

【讨论】:

    【解决方案2】:

    我一直在想,也许我可以在不实际执行的情况下获得无聊到实现的效果。我还没有实现这个,但我相信它应该可以工作:

    1. 编写一个不允许重新分配的自定义分配器my_allocator
    2. 我们现在可以使用 std::vector&lt;char, my_allocator&gt; 类,它使用各种 std::vector 包装原始缓冲区。
    3. 给定void* buf 和字节大小n,我们实例化一个包装向量:std::vector&lt;int, my_allocator&lt;int&gt;&gt; vec(n, {}, buf);
    4. 现在std::hash(vec) FTW!

    @hvd instructing me about this wrapping trick last year.

    【讨论】:

    • 我看不出这比std::hash 的任何其他用途更“可移植”。似乎这一切完成的是一个重言式:为了访问实现,您通过接口访问实现。
    • 你试过了吗?我不认为 std::hash 是为您的类型定义的。它是为std::vector&lt;bool&gt; 定义的,但不是为std::vector&lt;T&gt; 定义的(同样,因为最终现有标准没有组合哈希的概念,因此不支持对元组或范围进行哈希处理)。也许一些魔法可以让你的字节充当std::vector&lt;bool&gt; 中的位,但仅使用 Boost.Hash 会更清洁、更容易(并且可能更快)。
    • @ChristianHackl:你刚才说我无法访问实现,但如果这可行(它可能不可行) - 我可以。也就是说,这将对任意长度的(无类型)数据执行内部散列原语。
    • @GManNickG:Boost.Hash 本身非常好,但是 - 这不是我想要实现的(我也想限制我的库依赖)。
    • @einpoklum:我认为它无论如何都行不通。如果我按你说的做,VC 会给我error C2338: The C++ Standard doesn't provide a hash for this type。
    猜你喜欢
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多