Всегда допустимо преобразование указателя на тип в указатель на другой тип, включая void, поэтому, если T является типом, это допустимо в C++:
T* x;
void *y = reinterpret_cast<void *>(x);
В реальном мире он никогда не используется, потому что void *
— это особый случай, и вы получаете то же значение с static_cast
:
void *y = static_cast<void *>(x); // equivalent to previous reinterpret_cast
(на самом деле приведенное выше преобразование является неявным и может быть записано просто как void *y = x;
- спасибо Майклу Кензелу за то, что он это заметил)
Чтобы быть более точным, стандарт даже говорит в проекте n4659 для C++ 17 8.2.10 Reinterpret cast [expr.reinterpret.cast], §7
Когда prvalue v типа указателя объекта преобразуется в тип указателя объекта «указатель на cv T», результатом является static_cast<cv T*>(static_cast<cv void*>(v))
.
Когда вы ссылаетесь на то, что byte и char являются единственными допустимыми типами, просто допустимо разыменование преобразованного указателя только для этих типов. void
сюда не включено, потому что вы никогда не сможете разыменовать void *
.
Чтобы конкретно ответить на ваш вопрос
.. Я привожу от int** к void*. И в конце концов я переведу из void* обратно в int**.
Стандарт гарантирует, что первое преобразование является стандартным (читай, неявным):
Значение prvalue типа «указатель на cv T», где T — тип объекта, может быть преобразовано в значение prvalue типа «указатель на cv void». Значение указателя (6.9.2) при этом преобразовании не изменяется.
Так что это всегда законно:
int **i = ...;
void *v = i;
Для обратного кастинга стандарт говорит (в static_cast
параграфе):
Значение prvalue типа «указатель на cv1 void» может быть преобразовано в значение prvalue типа «указатель на cv2 T»,
Так это тоже законно
int **j = static_cast<int **>(v);
и стандарт гарантирует, что j == i
.
person
Serge Ballesta
schedule
17.04.2019
reinterpret_cast
для преобразования указателя вvoid*
. godbolt.org/z/-eIfjl - person Max Langhof   schedule 17.04.2019