diff --git a/src/json.hpp b/src/json.hpp
index 4efe51f7..8e1186ae 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8053,50 +8053,35 @@ class basic_json
             }
         }
 
-        /*
-        Use operator `const_iterator` instead of `const_iterator(const iterator&
-        other) noexcept` to avoid two class definitions for @ref iterator and
-        @ref const_iterator.
-
-        This function is only called if this class is an @ref iterator. If this
-        class is a @ref const_iterator this function is not called.
+        /*!
+        @note The conventional copy constructor and copy assignment are
+              implicitly defined.
+              Combined with the following converting constructor and assigment,
+              they support: copy from iterator to iterator,
+                            copy from const iterator to const iterator,
+                            and conversion from iterator to const iterator.
+              However conversion from const iterator to iterator is not defined.
         */
-        operator const_iterator() const
-        {
-            const_iterator ret;
-
-            if (m_object)
-            {
-                ret.m_object = m_object;
-                ret.m_it = m_it;
-            }
-
-            return ret;
-        }
 
         /*!
-        @brief copy constructor
-        @param[in] other  iterator to copy from
+        @brief converting constructor
+        @param[in] other  non-const iterator to copy from
         @note It is not checked whether @a other is initialized.
         */
-        iter_impl(const iter_impl& other) noexcept
+        iter_impl(const iter_impl<basic_json>& other) noexcept
             : m_object(other.m_object), m_it(other.m_it)
         {}
 
         /*!
-        @brief copy assignment
-        @param[in,out] other  iterator to copy from
+        @brief converting assignment
+        @param[in,out] other  non-const iterator to copy from
+        @return const/non-const iterator
         @note It is not checked whether @a other is initialized.
         */
-        iter_impl& operator=(iter_impl other) noexcept(
-            std::is_nothrow_move_constructible<pointer>::value and
-            std::is_nothrow_move_assignable<pointer>::value and
-            std::is_nothrow_move_constructible<internal_iterator>::value and
-            std::is_nothrow_move_assignable<internal_iterator>::value
-        )
+        iter_impl& operator=(const iter_impl<basic_json>& other) noexcept
         {
-            std::swap(m_object, other.m_object);
-            std::swap(m_it, other.m_it);
+            m_object = other.m_object;
+            m_it = other.m_it;
             return *this;
         }
 
@@ -8585,7 +8570,7 @@ class basic_json
         /// associated JSON instance
         pointer m_object = nullptr;
         /// the actual iterator of the associated instance
-        internal_iterator m_it = internal_iterator();
+        struct internal_iterator m_it = internal_iterator();
     };
 
     /*!
diff --git a/test/src/unit-iterators1.cpp b/test/src/unit-iterators1.cpp
index 6605076a..2dc9aae8 100644
--- a/test/src/unit-iterators1.cpp
+++ b/test/src/unit-iterators1.cpp
@@ -1511,4 +1511,72 @@ TEST_CASE("iterators 1")
             }
         }
     }
+
+    SECTION("conversion from iterator to const iterator")
+	{
+        SECTION("boolean")
+		{
+            json j = true;
+			json::const_iterator it = j.begin();
+			CHECK(it == j.cbegin());
+			it = j.begin();
+			CHECK(it == j.cbegin());
+		}
+        SECTION("string")
+		{
+            json j = "hello world";
+			json::const_iterator it = j.begin();
+			CHECK(it == j.cbegin());
+			it = j.begin();
+			CHECK(it == j.cbegin());
+		}
+        SECTION("array")
+		{
+            json j = {1, 2, 3};
+			json::const_iterator it = j.begin();
+			CHECK(it == j.cbegin());
+			it = j.begin();
+			CHECK(it == j.cbegin());
+		}
+        SECTION("object")
+		{
+            json j = {{"A", 1}, {"B", 2}, {"C", 3}};
+			json::const_iterator it = j.begin();
+			CHECK(it == j.cbegin());
+			it = j.begin();
+			CHECK(it == j.cbegin());
+		}
+        SECTION("number (integer)")
+		{
+            json j = 23;
+			json::const_iterator it = j.begin();
+			CHECK(it == j.cbegin());
+			it = j.begin();
+			CHECK(it == j.cbegin());
+		}
+        SECTION("number (unsigned)")
+		{
+            json j = 23u;
+			json::const_iterator it = j.begin();
+			CHECK(it == j.cbegin());
+			it = j.begin();
+			CHECK(it == j.cbegin());
+		}
+        SECTION("number (float)")
+		{
+            json j = 23.42;
+			json::const_iterator it = j.begin();
+			CHECK(it == j.cbegin());
+			it = j.begin();
+			CHECK(it == j.cbegin());
+		}
+        SECTION("null")
+		{
+            json j = nullptr;
+			json::const_iterator it = j.begin();
+			CHECK(it == j.cbegin());
+			it = j.begin();
+			CHECK(it == j.cbegin());
+		}
+	}
 }