diff --git a/include/msgpack/v1/adaptor/adaptor_base.hpp b/include/msgpack/v1/adaptor/adaptor_base.hpp
index 489362b4d..00a9af88f 100644
--- a/include/msgpack/v1/adaptor/adaptor_base.hpp
+++ b/include/msgpack/v1/adaptor/adaptor_base.hpp
@@ -12,6 +12,9 @@
 
 #include "msgpack/v1/adaptor/adaptor_base_decl.hpp"
 
+#include "msgpack/v1/cpp_config.hpp"
+
+
 namespace msgpack {
 
 /// @cond
@@ -21,13 +24,50 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
 
 namespace adaptor {
 
+// Unpack detector
+
+#ifndef MSGPACK_USE_CPP03
+
+namespace impl {
+
+template < typename T >
+using msgpack_unpack_t
+    = decltype( std::declval< T >().msgpack_unpack( std::declval< msgpack::object::implicit_type >() ) );
+
+template < typename T, typename = void_t<> >
+struct has_msgpack_unpack : std::false_type
+{};
+
+template < typename T >
+struct has_msgpack_unpack< T, void_t< impl::msgpack_unpack_t< T > > > : std::true_type
+{};
+
+} // namespace impl
+
+#endif
+
 // Adaptor functors
 
+#ifdef MSGPACK_USE_CPP03
+
 template <typename T, typename Enabler>
 struct convert {
     msgpack::object const& operator()(msgpack::object const& o, T& v) const;
 };
 
+#else
+
+template <typename T, typename Enabler>
+struct convert;
+
+template<typename T>
+struct convert<T, typename std::enable_if<adaptor::impl::has_msgpack_unpack<T>::value>::type>
+{
+    msgpack::object const &operator()(msgpack::object const &o, T &v) const;
+};
+
+#endif
+
 template <typename T, typename Enabler>
 struct pack {
     template <typename Stream>
diff --git a/include/msgpack/v1/cpp_config.hpp b/include/msgpack/v1/cpp_config.hpp
index 18d2a9a6d..7a17ac704 100644
--- a/include/msgpack/v1/cpp_config.hpp
+++ b/include/msgpack/v1/cpp_config.hpp
@@ -138,4 +138,24 @@ template<class T> struct is_pointer : detail::is_pointer_helper<typename remove_
 #define MSGPACK_DEPRECATED(msg)
 #endif // MSGPACK_CPP_VERSION >= 201402L
 
+
+#if !defined(MSGPACK_USE_CPP03) && MSGPACK_CPP_VERSION < 201703L
+
+namespace msgpack {
+
+/// @cond
+MSGPACK_API_VERSION_NAMESPACE(v1) {
+/// @endcond
+
+template<typename...> using void_t = void;
+
+/// @cond
+}  // MSGPACK_API_VERSION_NAMESPACE(v1)
+/// @endcond
+
+}  // namespace msgpack
+
+#endif
+
+
 #endif // MSGPACK_V1_CPP_CONFIG_HPP
diff --git a/include/msgpack/v1/cpp_config_decl.hpp b/include/msgpack/v1/cpp_config_decl.hpp
index 383a44511..b1bdce97d 100644
--- a/include/msgpack/v1/cpp_config_decl.hpp
+++ b/include/msgpack/v1/cpp_config_decl.hpp
@@ -87,6 +87,7 @@ struct is_pointer;
 
 #include <memory>
 #include <tuple>
+#include <type_traits>
 
 namespace msgpack {
 /// @cond
@@ -124,4 +125,23 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
 #define MSGPACK_HAS_INCLUDE(header) 0
 #endif // defined(__has_include)
 
+#if MSGPACK_CPP_VERSION >= 201703L
+
+namespace msgpack {
+/// @cond
+MSGPACK_API_VERSION_NAMESPACE(v1) {
+/// @endcond
+
+    // type_traits
+    using std::void_t;
+
+/// @cond
+}  // MSGPACK_API_VERSION_NAMESPACE(v1)
+/// @endcond
+}  // namespace msgpack
+
+
+#endif
+
+
 #endif // MSGPACK_V1_CPP_CONFIG_DECL_HPP
diff --git a/include/msgpack/v1/object.hpp b/include/msgpack/v1/object.hpp
index fda54be9f..8dc655b7c 100644
--- a/include/msgpack/v1/object.hpp
+++ b/include/msgpack/v1/object.hpp
@@ -640,10 +640,17 @@ struct packer_serializer {
 } // namespace detail
 
 // Adaptor functors' member functions definitions.
+#ifdef MSGPACK_USE_CPP03
 template <typename T, typename Enabler>
 inline
 msgpack::object const&
 adaptor::convert<T, Enabler>::operator()(msgpack::object const& o, T& v) const {
+#else
+template <typename T>
+inline
+msgpack::object const&
+adaptor::convert<T, typename std::enable_if<adaptor::impl::has_msgpack_unpack<T>::value>::type>::operator()(msgpack::object const& o, T& v) const {
+#endif
     v.msgpack_unpack(o.convert());
     return o;
 }
diff --git a/test/object.cpp b/test/object.cpp
index 1f6d7bbd8..ff6ea1970 100644
--- a/test/object.cpp
+++ b/test/object.cpp
@@ -562,3 +562,18 @@ BOOST_AUTO_TEST_CASE(array_unsigned_char)
 }
 
 #endif // MSGPACK_CPP_VERSION >= 201703
+
+#ifndef MSGPACK_USE_CPP03
+
+struct struct_without_adaptor
+{
+    int foo;
+};
+
+BOOST_AUTO_TEST_CASE(has_msgpack_unpack)
+{
+    static_assert(msgpack::v1::adaptor::impl::has_msgpack_unpack<struct_without_adaptor>::value == false, "");
+    static_assert(msgpack::v1::adaptor::impl::has_msgpack_unpack<myclass>::value, "");
+}
+
+#endif