реинтерпретация_приведения вектора одного типа к вектору другого типа того же типа

Я не уверен, что вопрос здесь отвечает на этот вопрос из-за странной формулировки, но:

если бы у меня был:

struct numpair
{
    some_type_with_a_size_of_2 a,b;
};

struct bignum
{
    some_type_with_a_size_of_4 a;
};

Могу ли я переинтерпретировать_привести вектор больших чисел к вектору числовых пар? Если нет, есть ли другие обходные пути, которые не требуют от меня создания нового вектора и повторной интерпретации каждого элемента?

редактировать: в окнах Visual Studio 2017, которые я использую, эти два типа имеют одинаковый размер.

изменить: теперь я узнал, если это строгое правило псевдонимов. Предполагается, что это двоичные данные, просматриваемые с помощью разных интерфейсов. Если оставить в стороне reinterpret_cast, могу ли я использовать объединение векторов этих типов?


person Evan    schedule 04.09.2017    source источник
comment
Вы абсолютно не можете переинтерпретировать это. литье между двумя совершенно не связанными нетривиальными типами... добром не кончится.   -  person Nir Friedman    schedule 05.09.2017
comment
Вы даже не можете переинтерпретировать_приведение между одним numpair и bignum.   -  person HolyBlackCat    schedule 05.09.2017
comment
это очень, странно. Я был уверен, что ты сможешь. Вы говорите это не потому, что у них разные размеры, верно? Я знаю, что вы не можете сделать это с двумя классами разного размера.   -  person Evan    schedule 05.09.2017
comment
Сама ваша идея полностью и полностью сломана. Это было бы правдой, даже если бы это не было вопиющим нарушением строгого алиасинга.   -  person Baum mit Augen    schedule 05.09.2017
comment
Почему вы хотите сделать это в первую очередь?   -  person Nir Friedman    schedule 05.09.2017
comment
мне нужен общий интерфейс для двух классов, содержащих одни и те же двоичные данные, но использующих их по-разному. Я разделяю вектор одного типа с другой частью моей программы, которая не должна знать этот тип со своим интерфейсом. @НирФридман   -  person Evan    schedule 05.09.2017
comment
Если предполагается, что он представляет двоичные данные, то один из типов должен быть массивом символов, тогда при определенных обстоятельствах было бы законно приведение. Если владелец вектора хочет разрешить пользователю доступ к вектору только как к одному из представлений, но не к другому, у вас есть 3 варианта. Самый простой способ — сохранить вектор как тот тип, который вы хотите выставить, и выполнить внутреннее преобразование. Во-вторых, владелец должен принять лямбду от клиента для доступа к данным. Третий — написать свои собственные итераторы.   -  person Nir Friedman    schedule 05.09.2017
comment
Возможно, было бы лучше, если бы вы задали новый вопрос, который дал пример кода того, что вы на самом деле пытаетесь выполнить, тогда я могу написать приведенные выше предложения более конкретно. Не стесняйтесь отметить меня здесь ссылкой, если вы решите это сделать.   -  person Nir Friedman    schedule 05.09.2017


Ответы (2)


struct A
{
    int x;
};

struct B
{
    int x;
};

Вы даже не можете переинтерпретировать приведение между этими двумя типами. Это нарушило бы строгое правило псевдонимов. Так что нет, вы не можете делать то, что хотите.

§3.10 L-значения и r-значения [basic.lval]

10. Если программа пытается получить доступ к сохраненному значению объекта через значение gl, отличное от одного из следующих типов, поведение не определено:54

  • динамический тип объекта,
  • cv-квалифицированная версия динамического типа объекта,
  • тип, аналогичный (как определено в 4.4) динамическому типу объекта,
  • тип, который является подписанным или беззнаковым типом, соответствующим динамическому типу объекта,
  • тип, который является подписанным или беззнаковым типом, соответствующим cv-квалифицированной версии динамического типа объекта,
  • агрегатный тип или тип объединения, который включает один из вышеупомянутых типов среди своих элементов или нестатических элементов данных (включая, рекурсивно, элемент или нестатический элемент данных подагрегата или содержащегося объединения),
  • тип, который является (возможно, cv-квалифицированным) типом базового класса динамического типа объекта, — тип char или unsigned char.

54) Цель этого списка состоит в том, чтобы указать те обстоятельства, при которых объект может или не может иметь псевдоним.

person bolov    schedule 04.09.2017

$ cat omg.cpp && g++ omg.cpp && echo ========== && ./a.out
#include <iostream>

struct numpair {
    unsigned short a,b;
};

struct bignum {
    unsigned long a;
};

int main() {
    std::cout << sizeof(numpair) << " != " << sizeof(bignum) << std::endl;
}
==========
4 != 8

Как вы думаете, почему типы одинаковы?

person bipll    schedule 04.09.2017
comment
когда я запустил этот код, я получил: 4 != 4 Нажмите любую клавишу, чтобы продолжить. . . Какая у вас операционная система? - person Evan; 05.09.2017
comment
@ Эван Тебе повезло. Это работает в Windows, в том смысле, что типы имеют одинаковый размер. Хотя это все еще незаконно. - person Baum mit Augen; 05.09.2017
comment
@BaummitAugen да, я почему-то думал, что длинное гарантированно будет в два раза длиннее короткого. По крайней мере, я не выучил это на собственном горьком опыте. - person Evan; 05.09.2017
comment
Неверный тест. Очевидно, что some_type_with_a_size_of_4 не является unsigned long на вашей платформе. - person user253751; 05.09.2017
comment
@immibis Вопрос был отредактирован таким образом, что делает ответ недействительным. Не вина Биплла. - person Baum mit Augen; 05.09.2017
comment
@ Эван Linux 4.12.8-2-ARCH #1 SMP PREEMPT Fri Aug 18 14:08:02 UTC 2017 x86_64 GNU/Linux и gcc version 7.1.1 20170630, если вам интересно. :) - person bipll; 06.09.2017