Явное преобразование типов и несколько простых спецификаторов типов
Чтобы значение инициализировать объект типа T
можно было бы сделать что-то вроде одного из следующих:
T x = T();
T x((T()));
Мой вопрос касается типов, указанных комбинацией простых спецификаторов типов, например, unsigned int
:
unsigned int x = unsigned int();
unsigned int x((unsigned int()));
Visual C++ 2008 и Intel C++ Compiler 11.1 принимают оба из них без предупреждений; Comeau 4.3.10.1b2 и g++ 3.4.5 (что, по общему признанию, не особенно новое) не делают.
Согласно стандарту C++ (C++03 5.2.3/2, expr.type.conv):
Выражение
T()
, гдеT
является спецификатором простого типа (7.1.5.2) для завершенного типа объекта, не являющегося массивом, или (возможно, cv-квалифицированного)void
type, создает значение r указанного типа, которое инициализируется значением
7.1.5.2 гласит "спецификаторы простого типа" и следует со списком, который включает unsigned
а также int
,
Поэтому, учитывая, что в 5.2.3 / 2 "простой спецификатор типа" является единственным, и unsigned
а также int
два спецификатора типа, приведенные выше примеры, которые используют unsigned int
недействительным? (и, если да, то разве это неправильно для Microsoft и Intel поддерживать указанные выражения?)
Этот вопрос скорее из любопытства, чем что-либо еще; для всех типов, указанных комбинацией нескольких простых спецификаторов типов, инициализация значения эквивалентна нулевой инициализации. (Этот вопрос был вызван комментариями в ответ на этот ответ на вопрос об инициализации).
4 ответа
Я разместил этот вопрос на comp.lang.C++. Модерируемый.
Даниэль Крюглер из комитета по стандартам C++ согласился с тем, что unsigned int
является комбинацией простых спецификаторов типов и не является простым спецификатором типов.
Относительно заголовка таблицы 7, на которую ссылается Джерри Коффин, Крюглер говорит:
Я согласен с тем, что заголовок таблицы 7 (которая является таблицей 9 в самом последнем проекте N3000) несколько вводит в заблуждение, но предыдущий текст в [dcl.type.simple]/2 кажется мне совершенно ясным, когда он говорит:
В таблице 7 приведены действительные комбинации спецификаторов простых типов и указанных типов ".
(Я прошу прощения, что мне понадобилось так много времени, чтобы опубликовать это здесь, в новостной группе; это полностью ускользнуло от меня)
В §7.1.5.2 продолжайте читать до таблицы 7, которая содержит полный список того, что разрешено в качестве простого спецификатора (который включает в себя "unsigned int").
Хм, иногда тебе нужен typedef. Если он не говорит, что требуется диагностика, значит, он не ошибается, чтобы поддержать это. Тем не менее, для переносимости, вы можете использовать typedef (uint16_t
или же uint64_t
, хотя это может быть и не правильно), или укажите имя типа с помощью шаблона:
iterator<void, unsigned long>::value_type( 5 )
Как это для необоснованно многословного?
Редактировать: Дух или просто 5ul
, Что оставляет unsigned short
, unsigned char
, а также signed char
как единственные типы, которые вы не можете легко сконструировать явно.
7.1.5.2:
Спецификаторы простого типа указывают либо ранее объявленный пользовательский тип, либо один из основных типов`
Это подразумевает, что unsigned int i = unsigned int()
законно, так как unsigned int
является фундаментальным типом (и, следовательно, спецификатором простого типа, см. 3.9.1).
То же самое относится к таким типам, как:
long double
long long
long long int
unsigned long
unsigned long long int
short int
...