Home > Software design >  use case for constructors for gsl::not_null taking value type
use case for constructors for gsl::not_null taking value type

Time:12-16

gsl::not_null has 2 constructors one taking a forwarding reference and another one taking a value type. What is the case where the forwarding constructor alone would not work? Implementation from here

template <class T>
class not_null
{
public:
    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))
    {
        Expects(ptr_ != nullptr);
    }

    template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
    constexpr not_null(T u) : ptr_(std::move(u))
    {
        Expects(ptr_ != nullptr);
    }
...

CodePudding user response:

Commit history gives the answer - https://github.com/microsoft/GSL/commit/cb2d1af89afb76bf50efe8e068c5ea1fc2872274

This allows compilers with c 17 support to infer template instantiation types when calling not_null constructor:

int foo(not_null<const int*> x);

int main()
{
    int t = 0;
    not_null x{ &t };
    return foo(not_null{ &t });
}

i.e. with this constructor you can write just not_null x{ &t } instead of not_null<int *> x{ &t }.

  •  Tags:  
  • c 11
  • Related