Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 4.60
Izual
93 / 118 / 6
Регистрация: 13.11.2012
Сообщений: 1,535
#1

Можно ли заменить обращение к Union без указания типа переменной? - C++

07.03.2014, 08:19. Просмотров 3166. Ответов 53
Метки нет (Все метки)

Можно ли заменить обращение к Union без указания типа переменной?(т.е. без .i .f .str, а просто к "data")
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <string.h>
 
union Data
{
   int i;
   float f;
   char  str[20];
};
 
int main( )
{
   union Data data;        
 
   data.i = 10;
   printf( "data.i : %d\n", data.i);
   
   data.f = 220.5;
   printf( "data.f : %f\n", data.f);
   
   strcpy( data.str, "C Programming");
   printf( "data.str : %s\n", data.str);
 
   return 0;
}
Что для этого надо сделать? Или есть под мои нужды альтернатива?

Добавлено через 7 минут
Т.е. чтоб при последующем использовании можно было бы сделать так:
C++
1
Lstrcat(data,"Empty");
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.03.2014, 08:19     Можно ли заменить обращение к Union без указания типа переменной?
Посмотрите здесь:

Как считать матрицу из файла без указания размерности? C++
C++ добавление в контейнер без указания типов данных?
Запуск MapInfo без указания пути в С++ Builder C++ Builder
C++ Есть две переменные типа int. Обменять их значения без использования третьей переменной
Как в переменной строкового типа заменить все вхождения одного символа на другой? C++
Можно ли использовать параметр шаблона без типа? C++
C++ Объединение нескольких массивов в одну область памяти Union и прямое обращение по имени
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
elivin
65 / 65 / 1
Регистрация: 04.01.2012
Сообщений: 231
Записей в блоге: 1
09.03.2014, 08:35     Можно ли заменить обращение к Union без указания типа переменной? #21
ValeryS, чтобы понять ход мыслей Izual'а, советую почитать эту тему. Много букв, конечно, но это поможет понять, что происходит в данной теме
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
11.03.2014, 01:05     Можно ли заменить обращение к Union без указания типа переменной? #22
Izual, единственный способ сделать это более или менее автоматически озвучен в четвертом посте. Кстати, пример в четвертом посте можно усовершенствовать в отношении удобства.

Правда все это сделает из POD union класс, а ты классы, помнится, юзать не хотел. Так что получается решения у этой задачи нет в поставленных условиях.
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
11.03.2014, 01:19     Можно ли заменить обращение к Union без указания типа переменной? #23
Цитата Сообщение от Izual Посмотреть сообщение
будет - переменная, а к ней по типу enum будет крепиться функция получения значения из конкретного типа.
зачем изобретать полиморфизм?
Izual
93 / 118 / 6
Регистрация: 13.11.2012
Сообщений: 1,535
12.03.2014, 16:14  [ТС]     Можно ли заменить обращение к Union без указания типа переменной? #24
Jupiter, очень тяжело гуглить "полиморфизм" под СИ, а не под С++, т.к. всё что с С++, то идёт с классами, а они априори МНЕ не подходят.

DrOffset, дада, я от этого поста и отталкиваюсь, только вот если у меня будет 100500 типов, то под каждый надо будет писать этот оператор - получится очень много кода, в таком случае оно не стоит того, и проще будет использовать обычный вид var.t.int. Нужна либо оптимизация, т.е. ну я предполагаю, может встроенная функция в структуре должна быть или что то ещё, но я пока не спец, потому предположить даже сложно.
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
12.03.2014, 19:06     Можно ли заменить обращение к Union без указания типа переменной? #25
Izual, зачем гуглить полиморфизм под С, когда это понятие вообще не привязанно к языку. Если в С нет классов, это не значит что полиморфизм там не возможен

Цитата Сообщение от Izual Посмотреть сообщение
получится очень много кода, в таком случае оно не стоит того
Не видел ни одной полноценной реализации вариантного типа, котором было бы "мало" кода...

Маленькое дополнение по union. Если мы положили в union int, то доставать из union мы тоже должны int. Любые другие комбинации - это неопределенное поведение. Например положив int и доставая double, мы никогда не получим корректного числа из-за принципиально разного битового представления этих типов.
Поэтому сам по себе union может быть полезен только для сжатого хранения разнотипной информации. Т.е. в довесок к union мы всегда должны писать проверки на текущее состояние union (что за тип там лежит) и функции преобразования из этого типа в требуемый.
Izual
93 / 118 / 6
Регистрация: 13.11.2012
Сообщений: 1,535
12.03.2014, 20:33  [ТС]     Можно ли заменить обращение к Union без указания типа переменной? #26
Цитата Сообщение от DrOffset Посмотреть сообщение
зачем гуглить полиморфизм под С, когда это понятие вообще не привязанно к языку
А примеры реализации я вам сам выдумаю? Может мне и новый язык создать?..
Цитата Сообщение от DrOffset Посмотреть сообщение
Если в С нет классов, это не значит что полиморфизм там не возможен
Плохо читаете! Я сказал следующее:
Цитата Сообщение от Izual Посмотреть сообщение
очень тяжело гуглить "полиморфизм" под СИ
Чуете разницу?..

Цитата Сообщение от DrOffset Посмотреть сообщение
было бы "мало" кода
Видели пример, когда под каждый тип нужно писать оператор? Одно дело когда только типы, а другое когда ещё и операторы. Утраивается размер кода. И опять же, я сказал:
Цитата Сообщение от Izual Посмотреть сообщение
Нужна либо оптимизация
...

Цитата Сообщение от DrOffset Посмотреть сообщение
проверки на текущее состояние union
А для чего я по вашему писал пример(*в 6 посте), где в структуре 2 переменные, одна - тип, вторая - сама переменная.

Это называется "То ли я дурак, то ли лыжи не едут". =)
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
12.03.2014, 21:13     Можно ли заменить обращение к Union без указания типа переменной? #27

Не по теме:

Izual, сколько экспрессии. Ну если я для тебя ничего нового не написал, так и скажи. Хамить-то зачем?



Добавлено через 3 минуты
Цитата Сообщение от Izual Посмотреть сообщение
очень тяжело гуглить "полиморфизм" под СИ
Я еще раз спрошу. Зачем гуглить "полиморфизм под Си", коли это понятие к языку не привязано?
Цитата Сообщение от Izual Посмотреть сообщение
А примеры реализации я вам сам выдумаю?
Конечно, а что тут такого? Если есть понятие что такое полиморфизм, то примеры реализации на языке, который знаешь, придумываются очень быстро К тому же ссылочка, которую я дал, содержит как раз пример для Си.
Izual
93 / 118 / 6
Регистрация: 13.11.2012
Сообщений: 1,535
12.03.2014, 21:22  [ТС]     Можно ли заменить обращение к Union без указания типа переменной? #28
DrOffset, я не хамлю, или по вашему если отвечать прямо - это хамство?.. Вот по мне так, хамство - это зайти в топик, не прочитать что написано, но ответить(это называется "слышу звон, да не знаю где он").(в итоге естественно "ахинея" получилась, так я ещё и хамлю...) Вот теперь у меня точно лыжи не едут.

*адд
примеры реализации на языке, который знаешь
Уровень знания тоже можно оценить по N бальной шкале. Я вообще мало знаю Си, на 2 балла из 100 наверно.
Evg
Эксперт CАвтор FAQ
17266 / 5520 / 343
Регистрация: 30.03.2009
Сообщений: 15,031
Записей в блоге: 26
12.03.2014, 22:12     Можно ли заменить обращение к Union без указания типа переменной? #29
Цитата Сообщение от ValeryS Посмотреть сообщение
Izual,
скажи зачем тебе union?
ты вообще представляешь что это такое?
что общего у int и float кроме размера?
А почему у int и float должно быть что-то общее?
Товарищ, судя по всему, пишет интерпретатор с языка программирования, а union - это внутреннее представление переменной (переменная может быть целая, вещественная или строковая). Чтобы что-то хранить в union'е, совсем необязательно, чтобы эти "что-то" имели что-то общее

Цитата Сообщение от Izual Посмотреть сообщение
Я для того и создал тему, чтобы найти инфу по инетересующему вопросу, тем более что как использовать в обычных условиях union это понятно. Но тут не тривиальный вопрос.
Считай, что ответ на твой вопрос - "нельзя". А куча встречных вопросов диктуется тем, что твой вопрос изначально является идиотским и люди хотят понять, ради чего разводится такой геморрой. Я, если честно, кроме экономии 5 букв ни одной разумной причины не понял
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
12.03.2014, 22:16     Можно ли заменить обращение к Union без указания типа переменной? #30

Не по теме:

Цитата Сообщение от Izual Посмотреть сообщение
я не хамлю, или по вашему если отвечать прямо - это хамство?
Да фраза твоя с дураком двусмысленно прозвучала. Но лично мне все равно в чью сторону она была направлена, мне просто интересно было зачем это вообще нужно делать



Цитата Сообщение от Izual Посмотреть сообщение
слышу звон, да не знаю где он
По-моему я дал совершенно корректную ссылку, между прочим с примерами, по прямой теме, которая до этого обсуждалась. Уточнив, что бессмысленно искать примеры полиморфизма на Си, если есть затруднения в самом предмете. Будешь с этим спорить?

Не по теме:

По поводу дополнения про union, да, я мне действительно было не очевидно, что у тебя есть полное понимание этой темы, поэтому я позволил себе написать пояснение. Ну раз я оказался не прав, то это только к лучшему. Однако, допущенная мной ошибка в суждении не достойна столь эмоциональной реакции. Лично я пришел сюда только затем, чтобы помогать людям.



Цитата Сообщение от Izual Посмотреть сообщение
Нужна либо оптимизация
Убрать синтаксический оверхед возможно. То есть я реально знаю способ, который позволит задать 1-N типов в union и получить автоматически операторы преобразования для всех них без необходимости вручную прописывать каждый оператор. Но это потребует использования С++ и его возможностей (в частности шаблонов). При условии, что ты писал о неприемлемости использования "новомодных" фич языка, я этот пример приводить не стал. А если оставаться в рамках Си или упрощенного Си++, то без ручного (или полуручного с помощью макросов) перечисления всех возможных вариантов не обойтись никак. Что и демонстрируют все известные мне реализации вариантных типов. Это я имел в виду, когда писал
Цитата Сообщение от DrOffset Посмотреть сообщение
полноценной реализации вариантного типа, в котором было бы "мало" кода...
.
ValeryS
Модератор
6479 / 4945 / 455
Регистрация: 14.02.2011
Сообщений: 16,386
12.03.2014, 22:19     Можно ли заменить обращение к Union без указания типа переменной? #31
Цитата Сообщение от Evg Посмотреть сообщение
А почему у int и float должно быть что-то общее?
ну наверно потому что он хочет конвертировать значения
типа записал в int а считал во float
Цитата Сообщение от Evg Посмотреть сообщение
Чтобы что-то хранить в union'е, совсем необязательно, чтобы эти "что-то" имели что-то общее
ну можно сказать( или нельзя ) что union это скрытое приведение

можно ведь и так написать
C++
1
2
3
int a=5;
float *b =(float*)&a;
float c=*b;
но это не значит что в c будет 5.0
Evg
Эксперт CАвтор FAQ
17266 / 5520 / 343
Регистрация: 30.03.2009
Сообщений: 15,031
Записей в блоге: 26
12.03.2014, 22:25     Можно ли заменить обращение к Union без указания типа переменной? #32
Цитата Сообщение от ValeryS Посмотреть сообщение
ну наверно потому что он хочет конвертировать значения
Это всего лишь твоё предположение. Наличие char[20] явно говорит о том, что предположение некорректное. Первоначальное назначение union'а - это хранить разнотипные значения, а не конвертировать битовые образы значений (последнее, строго говоря, противоречит strict aliasing rules)
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
12.03.2014, 22:27     Можно ли заменить обращение к Union без указания типа переменной? #33

Не по теме:

Цитата Сообщение от ValeryS Посмотреть сообщение
типа записал в int а считал во float
Не. Он уже дал понять своим ответом, что это не так.




Если текущий вопрос состоит именно в том, как он подан в его первом посте, то решение для него есть. Но оно не удовлетворит автора по религиозным причинам. Что еще предложить - лично я не знаю.
Могу привести код, если хотите.
Izual
93 / 118 / 6
Регистрация: 13.11.2012
Сообщений: 1,535
12.03.2014, 22:56  [ТС]     Можно ли заменить обращение к Union без указания типа переменной? #34
Evg, спасибо большое за разъяснения, у меня честно уже терпения не хватает. Люди выдумывают на ходу что хотят, а первые две страницы вообще не читали. Отсюда, ну не то чтобы я в бешенстве, но это уже не этично, и потому я уже начинаю думать что с стенкой разговариваю)))

Цитата Сообщение от Evg Посмотреть сообщение
кроме экономии 5 букв
Дело в том что я хочу динамики, т.е. всегда обращяться к переменной var[i](ну точнее, т.к. var это структура, то обращение будет к члену - union, тогда к var[i].v), а если делать по стандарту, то придётся под каждую функцию в последующем подписывать тип, что для меня является непонятным. Ведь если функция strcpy например в аргументе несёт тип char*, то ясен пень(опять лыжи не едут или у меня слишком идеальная логика, что создатели Си до этого не додумались) что var[i].v будет обращена к var[i].v.str (т.е. к char* типу), другое дело что типа такого нет например в моём union'е, но на это бы естественным образом при вызове функции вышла бы ошибка(ну это по логике), что мол - вы передали переменную, которая не имеет типа char*. (учитывая что логика основана НЕ на идеальных знаниях Си, о чём написал фразой "найти инфу")...

Цитата Сообщение от DrOffset Посмотреть сообщение
двусмысленно прозвучала
Ты всё правильно понял, она так и предполагала своё значение. Почему - потому что ты не читал первые две страницы, но написал комент, в итоге всё что ты написал - повторение того о чём уже было сказано. Вот после таких ответов - рождается оффтоп и тема уходит в отстой, либо продолжать её безсмысленно.
Цитата Сообщение от DrOffset Посмотреть сообщение
дал совершенно корректную ссылку
Знаеш фразу - "в бочке мёда ложка дёгтя"? Тут получилось наоборот "в бочке дёгтя ложка мёда", я потому и не зашёл на неё.(щяс зайду гляну)
Цитата Сообщение от DrOffset Посмотреть сообщение
примеры полиморфизма на Си, если есть затруднения в самом предмете
Предмет то как называется? ~ ~ (или вы думаете что я в вузе учусь - нет, отучился - бросил из за непоследовательности даваемых знаний, которые естественно не усваивались, потому что предыдущие этапы не были пройдены, это у нас в системе образования дырки)
Цитата Сообщение от DrOffset Посмотреть сообщение
помогать людям
"благими намерениями дорога в ад вымощена"... почему - потому что есть ещё целый пласт знаний и этики, кому и как давать, и другие производные вопросы - потому не каждый может являться учителем(вот видите, у меня даже принимаемая информация от первого вашего поста уже не воспринялась, имею ввиду ссылку), ну это не беда, мы потому и в этом матерриальном мире - потому что эгоистичны и не приняли бога и его канонов(это так философия вед, чтоб вы не расстраивались, а извлекли урок и учтя его - не наступали дважды на грабли)
Evg
Эксперт CАвтор FAQ
17266 / 5520 / 343
Регистрация: 30.03.2009
Сообщений: 15,031
Записей в блоге: 26
12.03.2014, 23:05     Можно ли заменить обращение к Union без указания типа переменной? #35
Цитата Сообщение от Izual Посмотреть сообщение
Люди выдумывают на ходу что хотят
Имеем два факта:

1. Ты не знаешь базовых основ языков Си и Си++, но полез делать что-то сложное, которое толком даже объяснить не можешь
2. Внятно поставленный вопрос - это половина ответа

В качестве результата ты получил ровно то, что должно в теории вытекать из этих двух фактов - кучу ответов на вопросы, которые ты не задавал и тебе не интересны.

Цитата Сообщение от Izual Посмотреть сообщение
Ведь если функция strcpy например в аргументе несёт тип char*, то ясен пень(опять лыжи не едут или у меня слишком идеальная логика, что создатели Си до этого не додумались) что var[i].v будет обращена к var[i].v.str
Я тебя огорчу, но у тебя лыжи не едут. В соответствии с п.1, описанным выше

Цитата Сообщение от Izual Посмотреть сообщение
Дело в том что я хочу динамики, т.е. всегда обращяться к переменной var[i]
Ты хочешь слишком много. В итоге получишь огромный геморрой, единственным позитивным моментом которого будет экономия 5 букв при написании кода.
Izual
93 / 118 / 6
Регистрация: 13.11.2012
Сообщений: 1,535
12.03.2014, 23:57  [ТС]     Можно ли заменить обращение к Union без указания типа переменной? #36
Цитата Сообщение от Evg Посмотреть сообщение
Ты не знаешь базовых основ языков Си и Си++
Ты тоже выдумщик я смотрю. "Базовые основы" это первые две главы любой нормальной книги по С/С++, это БАЗОВЫЕ ОСНОВЫ. Если ты не корректно выразился - получил что сказал.(ты же мне тут карму во плати устраиваеш, я потягяюсь ибо уже больше 5 лет варюсь в веданте)
Цитата Сообщение от Evg Посмотреть сообщение
полез делать что-то сложное
Я что должен на форуме простые вопросы поднимать, о которых в книгах написано? Вы видимо не поняли с кем имеете дело.
Цитата Сообщение от Evg Посмотреть сообщение
даже объяснить не можешь
Но почему то первые два ответа на первой странице были в точку по поставленному вопросу. Я лишь продолжил тему, которую мне подкинули в 4 посте - захотел автоматизации.(тут уже пошло поехало)
Цитата Сообщение от Evg Посмотреть сообщение
Внятно поставленный вопрос - это половина ответа
Кэп. Тем более что я сказал что я с ведами дела имею, ЛОГИЧНО же было предположить что я знаю и применяю написанную вами фразу.(повториться что первые два поста были корректны? т.е. первые двое поняли вопрос, остальные - нет? Так у кого тут лыжи то не едут?)
Цитата Сообщение от Evg Посмотреть сообщение
вытекать из этих двух фактов
Читай выше.
Цитата Сообщение от Evg Посмотреть сообщение
Я тебя огорчу
У меня тут книга под рукой "Программирование высокого уровня С/С++" автор Хабибулин. Книга считается уже не основой(не базовой основой так подавно), а средним+ уровнем, но в ней почему то не описано таких моментов.
Цитата Сообщение от Evg Посмотреть сообщение
Ты хочешь слишком много
Может к первому посту данной темы обратишся? Я по моему ясно задал вопрос, что мне нужна информация (можно или нельзя) +свои "религиозные принципы" как тут выразились. И в чём проблема? - Написал бы: "Имхо, нельзя." и пошёл бы дальше. Но нет, надо же в теме остановиться и устроить срач... Эй люди, здесь есть те кто знает слово "этика" и мудр(т.е. применяет знание этики)?..
Цитата Сообщение от Evg Посмотреть сообщение
экономия 5 букв
Ты подписывай "Имхо" рядом со своим комментом, чтобы не выглядело как "взгляд профессионала". Если ты не знаеш за чем - значит ты не напряг мозг или оно тебе не надо. Я лично знаю что мне надо и куда я двигаюсь, у меня уже 15000 строк кода рабочей программы. Вопрос в том что даёт язык Си того что я хочу или нет. Программирование - это логика, причём исходя из того что практически ничего не знал 2 года назад о Си(ну только совсем базу, которая даётся в книжках типа "С/С++ в задачах и примерах", т.е. умение пользоваться операторами, библ. функциями и построением алгоритмов), то очень уж странно, как же так за год я написал программу и изучил для её построения столько, сколько и вуз не даёт за 3 года, если вообще даёт?.. Это риторический вопрос, отвечать на него не надо. Это я к тому, что логика является базовым ключём к пониманию самой сути программирования. А вот то что я не знаю внутренностей(как устроено) таких вещей как union(ну в простых - обычных случаях, инфы по которой 99% я без проблем разбираюсь) это естественно, потому что тут уже извините, нужно 10 лет опыта, и т.п. Так для этого форум и создан, как факт того что люди изучающие глубоко программирование - могли бы делиться опытом. А вы начинаете упрекать меня в том что я куда то там залез в дебри. Не нравится - пройдите мимо, не провоцируйте.
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
13.03.2014, 00:00     Можно ли заменить обращение к Union без указания типа переменной? #37
Цитата Сообщение от DrOffset Посмотреть сообщение
Маленькое дополнение по union. Если мы положили в union int, то доставать из union мы тоже должны int. Любые другие комбинации - это неопределенное поведение.
C++
1
2
3
4
5
union foo_int
{
    int value;
    char bytes[sizeof(int)];
};
тоже неопределенное поведение? в общем давайте-ка цитату из стандарта

Не по теме:

мы настолько суровы, что разрабатываем под микроконтроллеры семейства Х с использованием компилятора от вендора Y, потому замечания о возможном различии порядка байт не принимаются

DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
13.03.2014, 01:56     Можно ли заменить обращение к Union без указания типа переменной? #38
Цитата Сообщение от Izual Посмотреть сообщение
Предмет то как называется?
Предмет разговора - "полиморфизм".

Цитата Сообщение от Izual Посмотреть сообщение
Ты всё правильно понял, она так и предполагала своё значение.
Значит и вывод я сделал верный, уж извини.

Цитата Сообщение от Izual Посмотреть сообщение
Тут получилось наоборот "в бочке дёгтя ложка мёда", я потому и не зашёл на неё
Ты преувеличиваешь.

Цитата Сообщение от Izual Посмотреть сообщение
почему - потому что есть ещё целый пласт знаний и этики, кому и как давать, и другие производные вопросы - потому не каждый может являться учителем
Учитывая, что ты не являешься экспертом в этом вопросе, и даже озвученный экспертом взгляд на этот вопрос был бы субъективен (особенно сделанный на основании одного единственного поста), позволю себе пропустить это замечание и последующую не относящуюся к теме философию мимо ушей


Итак, возвращаясь к теме:
Цитата Сообщение от Izual Посмотреть сообщение
Дело в том что я хочу динамики, т.е. всегда обращяться к переменной var[i](ну точнее, т.к. var это структура, то обращение будет к члену - union, тогда к var[i].v), а если делать по стандарту, то придётся под каждую функцию в последующем подписывать тип, что для меня является непонятным.
union в Си слишком базовая структура, чтобы к ней можно было применять высокоуровневую (в смысле высокого уровня абстракции) логику. Поэтому и не срастаются концы с концами. Есть два выхода - Первый - сменить язык. На более простой и более высокоуровневый. Там будет и рефлекшн, и встроенный вариантный тип, и решение многих других вопросов, с которыми тебе еще предстоит столкнуться в С и С++.
Второй выход воспользоваться приведенным ниже (или подобным) решением.
Хотя по моему мнению, это решение может быть применено только в чисто академических целях, причины этого озвучил Evg (не за чем ради 5ти лишних символов городить огород). Я оставляю это здесь будучи уверенным на 99%, что ты не будешь этим пользоваться. Однако, данная тема доступна всем и кому-то в целях изучения возможностей языка может быть интересно (требуется С++11):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <cstdio>
 
int main()
{
// это только пример написанный за полчаса и не претендует на полноту
    variant<char, float, int> var;
 
//var.type() возвращает индекс элемента union.
//по нему можно проверять корректность
 
// тип автоматически выбирается в зависимости от присваиваемого значения
    var = 2.3f; // тип float
    float v1 = var;
    printf("%0.1f - type %d\n", v1, var.type());
 
    var = 2;    // тип int
    int   v2 = var;
    printf("%d - type %d\n", v2, var.type());
 
    var = 'd';  // тип char
    int   v3 = var;
    printf("%c - type %d\n", v3, var.type());
 
    //var = 2.3; // тип double, ошибка компиляции
}
Реализация

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <type_traits>
 
// базовый тип для доступа
// standard-layout, на этом строятся все остальные допущения.
struct base_type { int type; };
 
// непосредственно значение
template <typename T>
struct declare_value : base_type { T value; };
 
// поиск индекса
template <typename UnionT, typename T, size_t Idx = 0, size_t Count = UnionT::size>
struct find_index
    : std::conditional
      <
          std::is_same<typename UnionT::head_t, declare_value<T>>::value
              , std::integral_constant<size_t, Idx>
              , find_index<typename UnionT::tail_t, T, Idx + 1>
      >::type
{ };
 
template <typename UnionT, typename T, size_t Idx>
struct find_index<UnionT, T, Idx, 1>
    : std::integral_constant<std::size_t, Idx>
{
    static_assert(std::is_same<typename UnionT::head_t, declare_value<T>>::value
                        , "Type is not allowed for this union");
};
 
// построение union исходя из кол-ва аргументов
template <typename Arg, typename ...Args>
struct union_traits
{
    union type
    {
        enum { size = sizeof...(Args) + 1 };
 
        typedef declare_value<Arg>                    head_t;
        typedef typename union_traits<Args...>::type tail_t;
 
        head_t head;
        tail_t tail;
    };
};
 
template <typename Arg>
struct union_traits<Arg>
{
    union type
    {
        enum { size = 1 };
 
        typedef declare_value<Arg>  head_t;
        typedef void               tail_t;
 
        head_t head;
    };
};
 
// интерфейс
template <typename ...Args>
struct variant
{
    typedef typename union_traits<Args...>::type union_t;
    union
    {
        union_t    value;
        base_type  generic;
    }
    value;
 
    template <typename T>
    variant & operator=(T const & val)
    {
        value.generic.type = find_index<union_t, T>::value;
        static_cast<declare_value<T> &>(value.generic).value = val;
        return *this;
    }
    template <typename T>
    operator T() const
    {
        return static_cast<declare_value<T> const &>(value.generic).value;
    }
    int type() const
    {
        return value.generic.type;
    }
    template <typename T>
    variant(T const & val)
    {
        value.generic.type = find_index<union_t, T>::value;
        static_cast<declare_value<T> &>(value.generic).value = val;
    }
    variant()
        : value()
    {}
};

Демонстрация

Добавлено через 11 минут
Цитата Сообщение от Jupiter Посмотреть сообщение
тоже неопределенное поведение? в общем давайте-ка цитату из стандарта
Да пожалуйста.
9.5/1
In a union, at most one of the non-static data members can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time.
Однако есть допущение, которое я использовал в своем примере, чтобы остаться в рамках стандарта:
Note: One special guarantee is made in order to simplify the use of unions: If a standard-layout union contains several standard-layout structs that share a common initial sequence (9.2), and if an object of this standard-layout union type contains one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of standard-layout struct members; see 9.2. —end note
Однако приведенный тобой пример к нему не относится.
Да, я знаю что этот union cast работает почти везде. Однако это не дает повода утверждать, что он стандартен
elivin
13.03.2014, 08:03
  #39

Не по теме:

Evg, тоже советую посмотреть эту тему, чтобы было ясно, что тут происходит (хотя, в данной теме тоже уже достаточно материала). По крайней мере, там есть:
1. чего вообще на самом деле хочет Izual
2. его реальный уровень (Вами, правда, уже определённый)

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.03.2014, 10:17     Можно ли заменить обращение к Union без указания типа переменной?
Еще ссылки по теме:

Возможно ли обращение к переменной с использованием значения строковой переменной? C++ Builder
Заменить символы в переменной типа String C++ Builder
C++ Цикл for без указания шага
Динамический массив без явного указания размера C++
Массив элементов типа Union C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
SatanaXIII
13.03.2014, 10:17     Можно ли заменить обращение к Union без указания типа переменной?
  #40
 Комментарий модератора 
Господа, в особенности уважаемый Izual, увижу еще один пост в котором будет два экрана обсуждения не особенностей языка, а друг друга, приму какие-нибудь меры.

P.S. Персонально для Izual: вы первый начали лезть в узкое место торцевой части морского огурца. Если вам так претит любая, пусть даже и не абсолютно четко по теме, критика, то может не стоит вообще ни с кем разговаривать?
P.P.S. Персонально для Evg: ну хочется человеку сократить пять букв. Вы попробовали отговорить от того, что по вашему кажется не разумным - не получилось. Теперь можете либо помочь ему в этом, либо не помочь.
Yandex
Объявления
13.03.2014, 10:17     Можно ли заменить обращение к Union без указания типа переменной?
Ответ Создать тему
Опции темы

Текущее время: 18:06. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru