diff --git a/src/json.hpp b/src/json.hpp index d238a28f..f7101d14 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -3073,8 +3073,11 @@ class basic_json @since version 2.1.0 */ - template ::value, int> = 0> + template < + typename T, + detail::enable_if_t::type, + basic_json_t>::value, + int> = 0 > basic_json get() const { return *this; @@ -3104,16 +3107,15 @@ class basic_json not detail::has_non_default_from_json::value, int > = 0 > - // do we really want the uncvref ? if a user call get, shouldn't we - // static assert ? - // i know there is a special behaviour for boolean_t* and such U get() const noexcept(noexcept(JSONSerializer::from_json( std::declval(), std::declval()))) { - static_assert(std::is_default_constructible::value and - std::is_copy_constructible::value, - "Types must be DefaultConstructible and " - "CopyConstructible when used with get"); + // we cannot static_assert on T being non-const, because there is support + // for get(), which is why we still need the uncvref + static_assert(not std::is_reference::value, "get cannot be used with reference types, you might want to use get_ref"); + static_assert(not std::is_pointer::value, "get cannot be used with pointer types, you might want to use get_ptr"); + static_assert(std::is_default_constructible::value, + "Types must be DefaultConstructible when used with get"); U ret; JSONSerializer::from_json(*this, ret); return ret; @@ -3143,6 +3145,8 @@ class basic_json int> = 0 > U get() const noexcept(noexcept(JSONSerializer::from_json(std::declval()))) { + static_assert(not std::is_reference::value, "get cannot be used with reference types, you might want to use get_ref"); + static_assert(not std::is_pointer::value, "get cannot be used with pointer types, you might want to use get_ptr"); return JSONSerializer::from_json(*this); } diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 9510cddc..65860c4d 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -3073,8 +3073,11 @@ class basic_json @since version 2.1.0 */ - template ::value, int> = 0> + template < + typename T, + detail::enable_if_t::type, + basic_json_t>::value, + int> = 0 > basic_json get() const { return *this; @@ -3104,16 +3107,14 @@ class basic_json not detail::has_non_default_from_json::value, int > = 0 > - // do we really want the uncvref ? if a user call get, shouldn't we - // static assert ? - // i know there is a special behaviour for boolean_t* and such U get() const noexcept(noexcept(JSONSerializer::from_json( std::declval(), std::declval()))) { - static_assert(std::is_default_constructible::value and - std::is_copy_constructible::value, - "Types must be DefaultConstructible and " - "CopyConstructible when used with get"); + // we cannot static_assert on T being non-const, because there is support + // for get(), which is why we still need the uncvref + static_assert(not std::is_reference::value, "get cannot be used with reference types, you might want to use get_ref"); + static_assert(std::is_default_constructible::value, + "Types must be DefaultConstructible when used with get"); U ret; JSONSerializer::from_json(*this, ret); return ret; @@ -3143,6 +3144,7 @@ class basic_json int> = 0 > U get() const noexcept(noexcept(JSONSerializer::from_json(std::declval()))) { + static_assert(not std::is_reference::value, "get cannot be used with reference types, you might want to use get_ref"); return JSONSerializer::from_json(*this); }