diff --git a/include/opendht/infohash.h b/include/opendht/infohash.h
index 40c1d254caa0c580cc83f11ba8405ba02447f55e..414c528b8a7cd79a402875d6a822b2ac7625b0fd 100644
--- a/include/opendht/infohash.h
+++ b/include/opendht/infohash.h
@@ -40,6 +40,7 @@ typedef uint16_t in_port_t;
 #include <iomanip>
 #include <array>
 #include <vector>
+#include <string_view>
 #include <algorithm>
 #include <stdexcept>
 #include <sstream>
@@ -66,10 +67,10 @@ public:
     typedef typename T::iterator iterator;
     typedef typename T::const_iterator const_iterator;
 
-    Hash () noexcept {
+    Hash() noexcept {
         data_.fill(0);
     }
-    Hash (const uint8_t* h, size_t data_len) {
+    Hash(const uint8_t* h, size_t data_len) {
         if (data_len < N)
             data_.fill(0);
         else
@@ -80,7 +81,12 @@ public:
      * hex must be at least 2.HASH_LEN characters long.
      * If too long, only the first 2.HASH_LEN characters are read.
      */
-    explicit Hash(const std::string& hex);
+    explicit Hash(std::string_view hex) {
+        if (hex.size() < 2*N)
+            data_.fill(0);
+        else
+            fromString(hex.data());
+    }
 
     Hash(const msgpack::object& o) {
         msgpack_unpack(o);
@@ -220,7 +226,7 @@ public:
         return v;
     }
 
-    static inline Hash get(const std::string& data) {
+    static inline Hash get(std::string_view data) {
         return get((const uint8_t*)data.data(), data.size());
     }
 
@@ -292,14 +298,6 @@ std::istream& operator>> (std::istream& s, Hash<N>& h)
     return s;
 }
 
-template <size_t N>
-Hash<N>::Hash(const std::string& hex) {
-    if (hex.size() < 2*N)
-        data_.fill(0);
-    else
-        fromString(hex.c_str());
-}
-
 template <size_t N>
 void
 Hash<N>::fromString(const char* in) {