Сначала на высоком уровне, что делает reinterpret_cast
?
- Преобразует любой тип указателя в любой другой тип указателя, даже из не связанных классов
- Приведение указателей к целочисленным типам или из них
Обратите внимание, что все, что здесь делается, включает приведение типов к указателям или к ним.Поэтому важно отметить, что reinterpret_cast<vector<Foo*>>(vf)
недопустимо, так как оно преобразует vector<void*>
в vector<Foo*>
.Несмотря на то, что это vector
s, которые содержат указатели, ни vf
, ни vector<Foo*>
сами по себе не являются указателями.
Обсудив это, давайте обсудим reinterpret_cast<vector<Foo*>*>(&vf)
это также приведет к неопределенному поведению, если его разыменовать из-за правил Тип псевдонима .
Учитывая, что входные данные для reinterpret_cast
- это DynamicType, а выходные данные - AliasedType, reinterpret_cast
допустимо только в том случае, если:
- AliasedType и DynamicType похожи
- AliasedType является (возможно, cv-квалифицированным) подписанным или неподписанным вариантом DynamicType
- AliasedTypeis
std::byte
, char
или unsigned char
: это разрешает проверку представления объекта любого объекта в виде массива байтов
Неформально два типа похожи, если, игнорируя верхний уровеньcv-qualification:
- Они имеют одинаковый тип
- Они оба указатели, а указываемые типы похожи
- Они оба указатели на члентого же класса, и тТипы элементов, на которые указывает указатель, аналогичны
- Они оба являются массивами одинакового размера или массивами с неизвестной границей, а типы элементов массива аналогичны
Так какничего из этого не верно в отношении vector<void*>*
и vector<Foo*>*
разыменования выходных данных этого reinterpret_cast
- неопределенное поведение.
Теперь, когда мы обсудили, почему они оба нежелательны;позвольте мне предложить вам вместо этого: void reportFooVector(void** pvf, const size_t count)
Вы можете вызвать это, выполнив: reportFooVector(data(vf), size(vf))
Внутри reportFooVector
вам нужно привести отдельные элементы к Foo*
с, чтобы работать с ними.