diff --git a/src/json.hpp b/src/json.hpp
index bd3c35f6..55dca29d 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -725,6 +725,18 @@ class basic_json
         return m_value.object->operator[](key);
     }
 
+    /// access specified element
+    inline const_reference operator[](const typename object_t::key_type& key) const
+    {
+        // at only works for objects
+        if (m_type != value_t::object)
+        {
+            throw std::runtime_error("cannot use [] with " + type_name());
+        }
+
+        return m_value.object->operator[](key);
+    }
+
     /// access specified element (needed for clang)
     template<typename T, size_t n>
     inline reference operator[](const T (&key)[n])
@@ -738,6 +750,19 @@ class basic_json
         return m_value.object->operator[](key);
     }
 
+    /// access specified element (needed for clang)
+    template<typename T, size_t n>
+    inline const_reference operator[](const T (&key)[n]) const
+    {
+        // at only works for objects
+        if (m_type != value_t::object)
+        {
+            throw std::runtime_error("cannot use [] with " + type_name());
+        }
+
+        return m_value.object->operator[](key);
+    }
+
 
     /// find an element in an object
     inline iterator find(typename object_t::key_type key)
@@ -1686,6 +1711,9 @@ class basic_json
         /// the category of the iterator
         using iterator_category = std::bidirectional_iterator_tag;
 
+        /// default constructor
+        inline iterator() = default;
+
         /// constructor for a given JSON instance
         inline iterator(pointer object) : m_object(object)
         {
@@ -2044,6 +2072,9 @@ class basic_json
         /// the category of the iterator
         using iterator_category = std::bidirectional_iterator_tag;
 
+        /// default constructor
+        inline const_iterator() = default;
+
         /// constructor for a given JSON instance
         inline const_iterator(pointer object) : m_object(object)
         {
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index e27a288a..25c5177f 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -725,6 +725,18 @@ class basic_json
         return m_value.object->operator[](key);
     }
 
+    /// access specified element
+    inline const_reference operator[](const typename object_t::key_type& key) const
+    {
+        // at only works for objects
+        if (m_type != value_t::object)
+        {
+            throw std::runtime_error("cannot use [] with " + type_name());
+        }
+
+        return m_value.object->operator[](key);
+    }
+
     /// access specified element (needed for clang)
     template<typename T, size_t n>
     inline reference operator[](const T (&key)[n])
@@ -738,6 +750,19 @@ class basic_json
         return m_value.object->operator[](key);
     }
 
+    /// access specified element (needed for clang)
+    template<typename T, size_t n>
+    inline const_reference operator[](const T (&key)[n]) const
+    {
+        // at only works for objects
+        if (m_type != value_t::object)
+        {
+            throw std::runtime_error("cannot use [] with " + type_name());
+        }
+
+        return m_value.object->operator[](key);
+    }
+
 
     /// find an element in an object
     inline iterator find(typename object_t::key_type key)
@@ -1686,6 +1711,9 @@ class basic_json
         /// the category of the iterator
         using iterator_category = std::bidirectional_iterator_tag;
 
+        /// default constructor
+        inline iterator() = default;
+
         /// constructor for a given JSON instance
         inline iterator(pointer object) : m_object(object)
         {
@@ -2044,6 +2072,9 @@ class basic_json
         /// the category of the iterator
         using iterator_category = std::bidirectional_iterator_tag;
 
+        /// default constructor
+        inline const_iterator() = default;
+
         /// constructor for a given JSON instance
         inline const_iterator(pointer object) : m_object(object)
         {