Почему const auto & p {nullptr} работает, а auto * p {nullptr} не работает в С++ 17?

Это определение работает:

const auto &b{nullptr};

в то время как это не удается:

auto *b{nullptr};

Я попытался скомпилировать это в Visual C++, GCC и Clang. Они все жалуются "не могут вывести тип".

Во втором случае не следует выводить b чтобы иметь какой-то тип типа std::nullptr_t?

Ответ 1

Это потому, что вы объявляете b указателем и инициализируете его как нулевой указатель. Но нулевой указатель на тот тип данных, который вы не говорите, поэтому компилятор не может вывести тип.

Если вы хотите, чтобы b был объектом std::nullptr_t, вы должны удалить звездочку:

auto b{nullptr};

Ответ 2

decltype(nullptr) - std::nullptr_t.

поэтому с

const auto &b{nullptr}; // auto is std::nullptr_t
// b is a reference to a temporary (with lifetime extension)

но nullptr НЕ является указателем (даже если он конвертируется в).

поэтому auto *b{nullptr}; является недействительным.

Вместо этого вы можете использовать

auto b{nullptr}; // auto is std::nullptr_t

Ответ 3

nullptr имеет тип std::nullptr_t. Поскольку значение nullptr не указывает ни на что, для std::nullptr_t не существует соответствующего типа std::nullptr_t (вам не разрешается разыменовать nullptr), следовательно

auto *b { nullptr};

запрашивает тип, которого не существует. Если вы хотите, чтобы b nullptr_t тип nullptr_t просто напишите

auto b { nullptr};