Хотя я не могу найти явного упоминания в этом рабочем проекте стандарта C ++ (с 2014 года) о том, что преобразование из std::nullptr_t
в целочисленный тип запрещено, также нет упоминания что такое преобразование разрешено!
Тем не менее, случай преобразования из std::nullptr_t
в bool
явно указан :
4.12 Булевы преобразования Значение арифметического c, перечисление с незаданной областью, указатель или указатель на тип элемента может быть преобразовано в значение типа bool. Нулевое значение, нулевое значение указателя или нулевое значение указателя члена преобразуется в ложь; любое другое значение преобразуется в true. Для прямой инициализации (8.5) значение типа std :: nullptr_t может быть преобразовано в значение типа bool; полученное значение равно false.
Кроме того, место only в этом черновом документе, где упоминается преобразование из std::nullptr_t
в целочисленный тип, находится в разделе «reinterpret_cast». :
5.2.10 Повторная интерпретация приведения ... (4) Указатель может быть явно преобразован в любой целочисленный тип, достаточно большой для его хранения. Функция отображения определяется реализацией. [Примечание: он предназначен для тех, кто знает структуру адресации базовой машины. - примечание конца] Значение типа std :: nullptr_t может быть преобразовано в целочисленный тип; преобразование имеет то же значение и действительность, что и преобразование (void *) 0 в целочисленный тип. [Примечание: reinterpret_cast нельзя использовать для преобразования значения любого типа в тип std :: nullptr_t. - примечание к концу]
Итак, из этих двух наблюдений можно (ИМХО) разумно предположить, что компилятор MSVC
верен.
РЕДАКТИРОВАТЬ : Тем не менее, использование вами «функциональной нотации» может фактически свидетельствовать об обратном! У компилятора MSVC
нет проблем с использованием приведения типа C, например:
uintptr_t answer = (uintptr_t)(nullptr);
, но (как в вашем коде) он жалуется на это:
uintptr_t answer = uintptr_t(nullptr); // error C2440: '<function-style-cast>': cannot convert from 'nullptr' to 'uintptr_t'
Тем не менее, из того же проекта стандарта:
5.2.3 Явное преобразование типов (функциональная запись) (1) Спецификатор простого типа (7.1.6.2) или спецификатор типа (14.6), за которым следует список выражений в скобках, создает значение указанного типа по заданному списку выражений. Если список выражений является одним выражением, выражение преобразования типа эквивалентно (в определенности и если определено в значении) соответствующему приведенному выражению (5.4). ...
«Соответствующее выражение приведения (5.4)» может относиться к приведению в стиле C.