C ++ 11 формализовал понятие сужение конверсии, и запрещено использовать один на верхнем уровне в списке инициализации.
Мне интересно, если, учитывая два типа T
а также U
, это может быть определено реализацией, является ли преобразование из T
в U
сужается. Согласно моему прочтению стандарта, это так. Вот мои рассуждения:
unsigned int
в long
,int
а также long
, C ++ требует только, чтобы sizeof(int) <= sizeof(long)
,sizeof(int) == sizeof(long)
, На этой реализации, long
не может представлять все значения unsigned int
, поэтому конверсия будет сужаться.sizeof(int) < sizeof(long)
, На этой реализации, long
может представлять все значения unsigned int
, поэтому конверсия не будет сужаться.Правильно ли я в своем анализе, что это может быть определено реализацией, сужается ли конверсия? Это желательно?
Я бы действительно предпочел, чтобы «сужающее преобразование» было определено для самих типов. Таким образом, чтобы int i{long(non_constant_expression)}
никогда не разрешается компилировать. Причина проста: либо вам не нужен большой радиус действия, вам следует использовать int
во-первых, или вы действительно хотите «вырезать», что кажется мне достаточно редким случаем, когда требуется явное преобразование типа или приведение. Чтобы ответить на первый вопрос: это определение реализации.
Но, если честно, я почти никогда не использую этот сырой тип, просто size_t
, int32_t
, uint16_t
и т.д., и это решает проблему автоматически. (uint16_t {uint8_t()}
всегда сужается, uint16_t{uint16_t()}
никогда.) Нужно только вдумчиво преобразовать size_t
во что-то другое, но это всегда так.
Других решений пока нет …