Почему допускается повторное интерпретирование целочисленных, перечислимых типов и указателей на элементы для себя? - PullRequest
6 голосов
/ 18 октября 2019

В этом недавнем вопросе мы увидели, что ему не разрешено reinterpret_cast создавать экземпляр некоторого пользовательского типа класса для себя;struct A{}; reinterpret_cast<A>(A{}); недействительно (работает только через ссылки или указатели). Что, кажется, имеет смысл, из-за отсутствия реальных сценариев, где необходимо такое преобразование идентичности.

Проверяя соответствующее стандартное предложение, мы имеем в [expr.reinterpret.cast] (выделение мое):

1 [...] Преобразования, которые могут быть выполнены явно с использованием reinterpret_­cast, перечислены ниже. Никакое другое преобразование не может быть выполнено явно с использованием reinterpret_­cast.

2 [...] Выражение целочисленного типа, перечисления, указателя или указателя на член может быть явно преобразовано в его собственноетип ;такое приведение дает значение своего операнда.

Так что reinterpret_cast<int>(42) разрешено, в то время как такое же приведение с struct A{} не разрешено. Почему?

1 Ответ

2 голосов
/ 18 октября 2019

Это было частью решения DR 799 . Проблема заключалась в следующем:

В примечании к пункту 2 статьи 8.2.10 [expr.reinterpret.cast] говорится:

С учетом ограничений, приведенных в этом разделе,выражение может быть приведено к своему собственному типу с использованием оператора reinterpret_cast.

Однако в нормативном тексте нет ничего, что разрешало бы это преобразование, и пункт 1 запрещает любое преобразование, прямо не разрешенное.

Идея в примечании была сочтена целесообразной, reinterpret_cast должно быть разрешено выполнять преобразование личности. Таким образом, был добавлен нормативный текст, о котором вы спрашиваете. Я могу предположить, что ограничение на некоторые фундаментальные типы является осторожным первым (и, может быть, даже единственным) шагом. Так как он не открывает банку с червями, связанную с типами классов и необходимостью вызывать их конструкторы. reinterpret_cast - это не создание новых объектов, и это можно сделать с помощью фундаментальных типов. Не уверен, что то же самое относится к типам классов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...