Why does const auto &p{nullptr} work while auto *p{nullptr} doesn't in C++17?
This definition works:
const auto &b{nullptr};
while this fails:
auto *b{nullptr};
I have tried to compile this in Visual C++, GCC, and Clang. They all complain "cannot deduce type".
In the second case, shouldn't b be deduced to have some type like std::nullptr_t?
It's because you declare b to be a pointer, and initialize it to be a null pointer. But a null pointer to what type of data you don't say, so the compiler can't deduce the type.
If you want b to be a std::nullptr_t object, you should drop the asterisk:
auto b{nullptr};
decltype(nullptr) is std::nullptr_t.
so with
const auto &b{nullptr}; // auto is std::nullptr_t
// b is a reference to a temporary (with lifetime extension)
but nullptr is NOT a pointer (even if it is convertible to).
so auto *b{nullptr}; is invalid.
You might use instead
auto b{nullptr}; // auto is std::nullptr_t
nullptr is of type std::nullptr_t. As a nullptr does not point to anything, there is no corresponding pointee type for std::nullptr_t (you are not allowed to dereference a nullptr), hence
auto *b { nullptr};
requests a type that does not exist. If you want b to be of type nullptr_t simply write
auto b { nullptr};
const auto &b{nullptr};
while this fails:
auto *b{nullptr};
I have tried to compile this in Visual C++, GCC, and Clang. They all complain "cannot deduce type".
In the second case, shouldn't b be deduced to have some type like std::nullptr_t?
It's because you declare b to be a pointer, and initialize it to be a null pointer. But a null pointer to what type of data you don't say, so the compiler can't deduce the type.
If you want b to be a std::nullptr_t object, you should drop the asterisk:
auto b{nullptr};
decltype(nullptr) is std::nullptr_t.
so with
const auto &b{nullptr}; // auto is std::nullptr_t
// b is a reference to a temporary (with lifetime extension)
but nullptr is NOT a pointer (even if it is convertible to).
so auto *b{nullptr}; is invalid.
You might use instead
auto b{nullptr}; // auto is std::nullptr_t
nullptr is of type std::nullptr_t. As a nullptr does not point to anything, there is no corresponding pointee type for std::nullptr_t (you are not allowed to dereference a nullptr), hence
auto *b { nullptr};
requests a type that does not exist. If you want b to be of type nullptr_t simply write
auto b { nullptr};
Comments
Post a Comment