Rumah >pembangunan bahagian belakang >C++ >Bagaimana untuk Melaksanakan Fungsi Hash Generik untuk Tuple dalam Koleksi Tidak Tertib?

Bagaimana untuk Melaksanakan Fungsi Hash Generik untuk Tuple dalam Koleksi Tidak Tertib?

DDD
DDDasal
2024-11-15 09:21:02499semak imbas

How to Implement a Generic Hash Function for Tuples in Unordered Collections?

Fungsi Hash Generik untuk Tuple dalam Koleksi Tidak Tertib

Bekas std::unordered_map dan std::unordered_set menyediakan carian dan pemasukan elemen yang cekap berdasarkan nilai cincang mereka. Walau bagaimanapun, menggunakan tupel sebagai kunci dalam koleksi ini tanpa mentakrifkan fungsi cincang tersuai boleh membawa kepada gelagat yang tidak dijangka.

Untuk membetulkannya, satu pendekatan ialah mentakrifkan fungsi cincang secara manual untuk jenis tuple tertentu, seperti:

template<>
struct std::hash<std::tuple<int, int>> {
  size_t operator()(std::tuple<int, int> const& tuple) const { ... }
};

Sementara pendekatan ini berfungsi, ia boleh membosankan untuk menentukan fungsi cincang untuk setiap jenis tupel yang digunakan. Untuk mengautomasikannya, fungsi cincang generik boleh dilaksanakan seperti berikut:

#include <tuple>

namespace std {
  namespace {

    // Code derived from Boost
    template<class T>
    inline void hash_combine(std::size_t& seed, T const& v) { ... }

    // Recursive template code from Matthieu M.
    template<class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1>
    struct HashValueImpl { ... };

  }

  template<typename... TT>
  struct hash<std::tuple<TT...>> {
    size_t operator()(std::tuple<TT...> const& tuple) const { ... }
  };
}

Fungsi ini memanfaatkan carian nama bergantung pada argumen (ADL) untuk membolehkan pengkompil memilih pelaksanaan cincang yang betul berdasarkan jenis tuple secara automatik .

Penyelesaian Conformant Standard

Perlu diambil perhatian bahawa mentakrifkan fungsi bukan standard dalam ruang nama std ialah tingkah laku yang tidak ditentukan. Untuk penyelesaian yang mematuhi piawaian, ruang nama tersuai boleh dibuat dan digunakan untuk mentakrifkan fungsi cincang:

namespace my_hash {

  // Forward non-tuple types to the std::hash
  template<typename TT>
  struct hash { ... };

  // Provide the optimized hash for tuples
  template<typename... TT>
  struct hash<std::tuple<TT...>> { ... };

}

Apabila menggunakan penyelesaian ini, koleksi yang tidak tertib mesti merujuk pelaksanaan cincang tersuai secara eksplisit seperti berikut:

unordered_set<
  std::tuple<double, int>,
  std::hash<std::tuple<double, int>>,
  std::equal_to<std::tuple<double, int>>
> test;  

Atas ialah kandungan terperinci Bagaimana untuk Melaksanakan Fungsi Hash Generik untuk Tuple dalam Koleksi Tidak Tertib?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn