Hash Sets using std::unordered_set

Using std::unordered_set with Smart Pointers

How can I store smart pointers like std::unique_ptr in a std::unordered_set?

Abstract art representing computer programming

To store smart pointers like std::unique_ptr in a std::unordered_set, you need to provide a custom hash function and a custom equality comparator that operate on the underlying raw pointers.

Here's an example of using std::unique_ptr with std::unordered_set:

#include <iostream>
#include <memory>
#include <unordered_set>

struct Player {
  std::string Name;
  int Score;

  Player(const std::string& Name, int Score)
    : Name{Name}, Score{Score} {}
};

struct PlayerHash {
  size_t operator()(
    const std::unique_ptr<Player>& P) const {
    return std::hash<Player*>{}(P.get());  
  }
};

struct PlayerEqual {
  bool operator()(
    const std::unique_ptr<Player>& A,
    const std::unique_ptr<Player>& B
  ) const {
    return A.get() == B.get();  
  }
};

int main() {
  std::unordered_set<std::unique_ptr<Player>,
    PlayerHash, PlayerEqual> Players;  

  Players.emplace(
    std::make_unique<Player>("Alice", 100));
  Players.emplace(
    std::make_unique<Player>("Bob", 200));

  for (const auto& Player : Players) {
    std::cout << Player->Name << ": "
      << Player->Score << "\n";
  }
}
Alice: 100
Bob: 200

In this example:

  • We define a Player struct with Name and Score members
  • We create a PlayerHash struct that overloads operator() to hash the raw pointer stored inside the std::unique_ptr
  • We create a PlayerEqual struct that overloads operator() to compare the raw pointers stored inside the std::unique_ptrs for equality
  • We specify std::unique_ptr<Player> as the key type and provide PlayerHash and PlayerEqual as the hash function and equality comparator when creating the std::unordered_set
  • We use std::make_unique to create std::unique_ptr<Player> objects and insert them into the set using emplace()

By providing custom hash and equality functions that operate on the raw pointers, we enable std::unordered_set to store and compare std::unique_ptr<Player> objects correctly.

Note that using smart pointers in an unordered set compares the pointers themselves, not the objects they point to. If you want to compare the pointed-to objects, you'll need to dereference the smart pointers in your custom comparator and hash function.

 

Answers to questions are automatically generated and may not have been reviewed.

Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved