Хотя я не могу найти явного упоминания в этом рабочем проекте C ++ Standard (от 2014 года), что преобразование std::nullptr_t
в целочисленный тип запрещено, также нет упоминания о том, что такое преобразование разрешено!
Однако, в случае перехода от std::nullptr_t
To bool
будет явно упомянуто:
4.12. Булевы преобразования
. Значение арифметики, перечисление с незаданной областью, указатель или указатель на тип элемента может быть преобразовано в значение типа bool. Нулевое значение, нулевое значение указателя или нулевое значение указателя члена преобразуется в ложь; любое другое значение преобразуется в true. Для прямой инициализации (8.5) значение типа std :: nullptr_t можно преобразовать в значение типа bool; результирующее значение ложно.
Кроме того, единственное место в этом проекте документа, где 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) или спецификатор typename (14.6), за которым следует список выражений в скобках, создает значение указанного типа по заданному списку выражений. Если список выражений является одним выражением, выражение преобразования типа эквивалентно (в определенности и если определено в значении) соответствующему приведенному выражению (5.4). ...
«Соответствующее выражение приведения (5.4)» может относиться к приведению в стиле C.