Const приведение к не указателю не ссылочного типа - PullRequest
1 голос
/ 03 апреля 2020

С [expr.const.cast] / 3 :

Для двух аналогичных типов T1 и T2 значение типа T1 может быть явно преобразовано в тип T2 использование const_cast, если, учитывая cv-разложения обоих типов, каждый P i 1 совпадает с P i 2 для всех i . Результат const_cast ссылается на исходную сущность.

Похоже, что const приведен к не указателю не ссылочного типа. Например, следующая функция

void f(int a)
{
    const_cast<int>(a);
}

должна быть правильно сформирована, поскольку int и int, безусловно, являются похожими типами и не имеют P i. в их cv-разложениях (таким образом, утверждение, что «каждый P i 1 совпадает с P i 2 для всех i"должно быть истинным).

Однако оба G CC и Clang отклоняют приведенный выше код (см. Проводник компилятора ). Сообщения об ошибках:

Clang:

<source>: In function 'void f(int)':
<source>:3:22: error: invalid use of const_cast with type 'int', which is not a pointer, reference, nor a pointer-to-data-member type
    3 |     const_cast<int>(a);
      |                      ^

G CC:

<source>: In function 'void f(int)':
<source>:3:5: error: invalid use of 'const_cast' with type 'int', which is not a pointer, reference, nor a pointer-to-data-member type
    3 |     const_cast<int>(a);
      |     ^~~~~~~~~~~~~~~~~~

Я что-то упустил или это ошибка компилятора?

ОБНОВЛЕНИЕ : это тоже не работает:

void f()
{
    const_cast<int>(int{});
}

1 Ответ

1 голос
/ 03 апреля 2020

В C ++ 17 типы не похожи , поэтому цитируемый текст не применяется. И поэтому это const_cast недопустимо, поскольку const_cast не допускается, если явно не разрешено.

C ++ 17 [conv.qual] / 1:

A cv-разложение типа T представляет собой последовательность cv i и P i , такую ​​что T is

cv 0 P 0 cv 1 P 1 ··· cv n- 1 P n-1 cv n U для n> 0 ,

, где каждый cv i является набором cv-квалификаторов (6.9.3), и каждый P i является «указателем на» (11.3.1), «указателем на члена класса C i типа »(11.3.3),« массив N i »или« массив неизвестных границ »(11.3.4). [...]

, а затем

Два типа T 1 и T 2 похожи, если они имеют cv -разложения с одинаковыми n , так что соответствующие компоненты P i одинаковы, а типы, обозначенные U, одинаковы.

Требование n> 0 означает, что должен быть cv 0 P 0 , то есть как минимум один указатель в типе.


последние изменения в C ++ 20 n> 0 до n ≥ 0 , в результате выпуск 2051 . Но не меняет спецификацию const_cast. Я не могу сказать, является ли это преднамеренным или упущением.

Так что, возможно, C ++ 20 сделает ваши выражения const_cast четко определенными, и компиляторам придется наверстать упущенное.

...