Явное преобразование типов и несколько простых спецификаторов типов - PullRequest
8 голосов
/ 27 января 2010

Чтобы значение инициализировало объект типа 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, создает значение r указанный тип, который инициализируется значением

7.1.5.2 говорит «спецификаторы простого типа» и следует со списком, включающим unsigned и int.

Поэтому, учитывая, что в 5.2.3 / 2 «простой спецификатор типа» является единственным, а unsigned и int являются двумя спецификаторами типа, являются ли приведенные выше примеры, в которых используется unsigned int недопустимым? (и, если да, то разве это неправильно для Microsoft и Intel поддерживать указанные выражения?)

Этот вопрос скорее из любопытства, чем что-либо еще; для всех типов, указанных комбинацией нескольких простых спецификаторов типов, инициализация значения эквивалентна нулевой инициализации. (Этот вопрос был вызван комментариями в ответ на этот ответ на вопрос об инициализации ).

Ответы [ 4 ]

8 голосов
/ 12 марта 2010

Я разместил этот вопрос на comp.lang.c ++. Модерируемый .

Даниэль Крюглер из комитета по стандартам C ++ согласился с интерпретацией, что unsigned int представляет собой комбинацию простых спецификаторов типов и сам по себе не является простым спецификатором типов.

Относительно заголовка таблицы 7 , на которую ссылается Джерри Коффин , Крюглер говорит:

Я согласен, что заголовок таблицы 7 (которая является таблицей 9 в большинстве Последний проект N3000) несколько вводит в заблуждение, но предшествующий текст в [dcl.type.simple] / 2 кажется мне очень понятным, когда он говорит:

В таблице 7 приведены действительные комбинации простых спецификаторов типов. и типы, которые они указывают. "

(я прошу прощения, что я занял так много времени, чтобы опубликовать это здесь из новостной группы; это полностью ускользнуло от меня)

1 голос
/ 27 января 2010

В §7.1.5.2 продолжайте чтение до таблицы 7, в которой содержится полный список того, что разрешено в качестве простого спецификатора (который включает в себя "unsigned int").

1 голос
/ 27 января 2010

Хм, иногда вам нужен typedef. Если он не говорит, что требуется диагностика, значит, он не ошибается, чтобы поддержать это. Тем не менее, для переносимости вы можете использовать typedef (uint16_t или uint64_t, хотя они могут быть не правы), или указывать имя типа с помощью шаблона:

iterator<void, unsigned long>::value_type( 5 )

Как это для необоснованно многословного?

Редактировать: Дух или просто 5ul. Это оставляет unsigned short, unsigned char и signed char как единственные типы, которые вы не можете легко сконструировать явно.

0 голосов
/ 27 января 2010

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
...
...