diff --git a/include/tsl/robin_hash.h b/include/tsl/robin_hash.h
index 5fdc07f..525ad34 100644
--- a/include/tsl/robin_hash.h
+++ b/include/tsl/robin_hash.h
@@ -356,7 +356,8 @@ class bucket_entry : public bucket_entry_hash<StoreHash> {
  * Behaviour is undefined if the destructor of `ValueType` throws.
  */
 template <class ValueType, class KeySelect, class ValueSelect, class Hash,
-          class KeyEqual, class Allocator, bool StoreHash, class GrowthPolicy>
+          class KeyEqual, class Allocator, bool StoreHash, class GrowthPolicy,
+          class ValueTypeIt>
 class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
  private:
   template <typename U>
@@ -387,6 +388,12 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
   using iterator = robin_iterator<false>;
   using const_iterator = robin_iterator<true>;
 
+  using value_type_it = ValueTypeIt;
+  using reference_it = value_type_it&;
+  using const_reference_it = const value_type_it&;
+  using pointer_it = value_type_it*;
+  using const_pointer_it = const value_type_it*;
+
  private:
   /**
    * Either store the hash because we are asked by the `StoreHash` template
@@ -463,10 +470,16 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
 
    public:
     using iterator_category = std::forward_iterator_tag;
-    using value_type = const typename robin_hash::value_type;
+    using value_type = typename robin_hash::value_type_it;
     using difference_type = std::ptrdiff_t;
-    using reference = value_type&;
-    using pointer = value_type*;
+    using reference =
+        typename std::conditional<IsConst,
+                                  typename robin_hash::const_reference_it,
+                                  typename robin_hash::reference_it>::type;
+    using pointer =
+        typename std::conditional<IsConst,
+                                  typename robin_hash::const_pointer_it,
+                                  typename robin_hash::pointer_it>::type;
 
     robin_iterator() noexcept {}
 
@@ -499,9 +512,13 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
       return U()(m_bucket->value());
     }
 
-    reference operator*() const { return m_bucket->value(); }
+    reference operator*() const {
+      return reinterpret_cast<reference>(m_bucket->value());
+    }
 
-    pointer operator->() const { return std::addressof(m_bucket->value()); }
+    pointer operator->() const {
+      return reinterpret_cast<pointer>(std::addressof(m_bucket->value()));
+    }
 
     robin_iterator& operator++() {
       while (true) {
diff --git a/include/tsl/robin_map.h b/include/tsl/robin_map.h
index aeb354c..496a34d 100644
--- a/include/tsl/robin_map.h
+++ b/include/tsl/robin_map.h
@@ -105,6 +105,15 @@ class robin_map {
     key_type& operator()(std::pair<Key, T>& key_value) noexcept {
       return key_value.first;
     }
+
+    const key_type& operator()(
+        const std::pair<const Key, T>& key_value) const noexcept {
+      return key_value.first;
+    }
+
+    const key_type& operator()(std::pair<const Key, T>& key_value) noexcept {
+      return key_value.first;
+    }
   };
 
   class ValueSelect {
@@ -121,9 +130,10 @@ class robin_map {
     }
   };
 
-  using ht = detail_robin_hash::robin_hash<std::pair<Key, T>, KeySelect,
-                                           ValueSelect, Hash, KeyEqual,
-                                           Allocator, StoreHash, GrowthPolicy>;
+  using ht =
+      detail_robin_hash::robin_hash<std::pair<Key, T>, KeySelect, ValueSelect,
+                                    Hash, KeyEqual, Allocator, StoreHash,
+                                    GrowthPolicy, std::pair<const Key, T>>;
 
  public:
   using key_type = typename ht::key_type;
diff --git a/include/tsl/robin_set.h b/include/tsl/robin_set.h
index 5478950..61099d9 100644
--- a/include/tsl/robin_set.h
+++ b/include/tsl/robin_set.h
@@ -101,8 +101,9 @@ class robin_set {
     key_type& operator()(Key& key) noexcept { return key; }
   };
 
-  using ht = detail_robin_hash::robin_hash<Key, KeySelect, void, Hash, KeyEqual,
-                                           Allocator, StoreHash, GrowthPolicy>;
+  using ht =
+      detail_robin_hash::robin_hash<Key, KeySelect, void, Hash, KeyEqual,
+                                    Allocator, StoreHash, GrowthPolicy, Key>;
 
  public:
   using key_type = typename ht::key_type;