diff options
author | beinhaerter <34543625+beinhaerter@users.noreply.github.com> | 2021-02-25 01:39:13 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-25 01:39:13 +0300 |
commit | ef0ffefe525a6219ff245d19a832ce06f3fd3504 (patch) | |
tree | 0ad7ca11acaf804fc5734fe27e045af272095570 | |
parent | 176c92e802456f1c52ccd99c0a34d5b1cc6ea020 (diff) |
is_comparable_to_nullptr for better static_assert (#975)
* is_comparable_to_nullptr for better static_assert
Trying `gsl::not_null<char> p2{ 0 };` on VS2019 the current implementation would trigger
>error C2446 : '!=' : no conversion from 'nullptr' to 'int'
>message: A native nullptr can only be converted to bool or , using reinterpret_cast, to an integral type
>message: see reference to class template instantiation 'gsl::not_null<char>' being compiled
>error C2955 : 'std::is_convertible' : use of class template requires template argument list
>message: see declaration of 'std::is_convertible'
>error C2039 : 'value' : is not a member of 'std::is_convertible<_From,_To>'
>error C2065 : 'value' : undeclared identifier
The new implementation gives much shorter and clearer message and does exactly as the `static_assert` intends to do:
> error C2338: T cannot be compared to nullptr.
> message : see reference to class template instantiation 'gsl::not_null<char *>' being compiled
* Update include/gsl/pointers
Co-authored-by: Casey Carter <cartec69@gmail.com>
Co-authored-by: Werner Henze <w.henze@avm.de>
Co-authored-by: Casey Carter <cartec69@gmail.com>
-rw-r--r-- | include/gsl/pointers | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/include/gsl/pointers b/include/gsl/pointers index 42e8c09..2f1b15f 100644 --- a/include/gsl/pointers +++ b/include/gsl/pointers @@ -32,6 +32,15 @@ namespace gsl { +namespace details +{ +template<typename T, typename = void> +struct is_comparable_to_nullptr : std::false_type {}; + +template <typename T> +struct is_comparable_to_nullptr<T, std::enable_if_t<std::is_convertible<decltype(std::declval<T>() != nullptr), bool>::value>> : std::true_type {}; +} // namespace details + // // GSL.owner: ownership pointers // @@ -68,8 +77,7 @@ template <class T> class not_null { public: - static_assert(std::is_convertible<decltype(std::declval<T>() != nullptr), bool>::value, - "T cannot be compared to nullptr."); + static_assert(details::is_comparable_to_nullptr<T>::value, "T cannot be compared to nullptr."); template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>> constexpr not_null(U&& u) : ptr_(std::forward<U>(u)) |