143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
1

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

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

Author24 — интернет-сервис помощи студентам
Можно ли заменить обращение к 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");
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.03.2014, 08:19
Ответы с готовыми решениями:

О структурах. Как в массив записываются элементы разных типов без указания собственно типа?
Имеется следующая программа #include &quot;stdafx.h&quot;; #include &lt;iostream&gt; #include &lt;string&gt; ...

Можно ли передать переменную в класс без указания ее типа
Есть универсальный класс. С дофига и более функциями. И при работе с классом приходится постоянно...

Обращение к файлу без указания полного пути
Народ, у меня такая проблема. Тут не objective-c а просто shell скрипт. Я создал программу, которой...

Массив с единственной ячейкой: можно ли обращаться к нему без указания индекса?
Есть вопрос: если в массиве инициализирована всего одна ячейка, и иначе не предвидется в ходе...

53
67 / 67 / 9
Регистрация: 04.01.2012
Сообщений: 231
Записей в блоге: 1
09.03.2014, 08:35 21
Author24 — интернет-сервис помощи студентам
ValeryS, чтобы понять ход мыслей Izual'а, советую почитать эту тему. Много букв, конечно, но это поможет понять, что происходит в данной теме
0
18822 / 9826 / 2401
Регистрация: 30.01.2014
Сообщений: 17,260
11.03.2014, 01:05 22
Izual, единственный способ сделать это более или менее автоматически озвучен в четвертом посте. Кстати, пример в четвертом посте можно усовершенствовать в отношении удобства.

Правда все это сделает из POD union класс, а ты классы, помнится, юзать не хотел. Так что получается решения у этой задачи нет в поставленных условиях.
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
11.03.2014, 01:19 23
Цитата Сообщение от Izual Посмотреть сообщение
будет - переменная, а к ней по типу enum будет крепиться функция получения значения из конкретного типа.
зачем изобретать полиморфизм?
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
12.03.2014, 16:14  [ТС] 24
Jupiter, очень тяжело гуглить "полиморфизм" под СИ, а не под С++, т.к. всё что с С++, то идёт с классами, а они априори МНЕ не подходят.

DrOffset, дада, я от этого поста и отталкиваюсь, только вот если у меня будет 100500 типов, то под каждый надо будет писать этот оператор - получится очень много кода, в таком случае оно не стоит того, и проще будет использовать обычный вид var.t.int. Нужна либо оптимизация, т.е. ну я предполагаю, может встроенная функция в структуре должна быть или что то ещё, но я пока не спец, потому предположить даже сложно.
0
18822 / 9826 / 2401
Регистрация: 30.01.2014
Сообщений: 17,260
12.03.2014, 19:06 25
Izual, зачем гуглить полиморфизм под С, когда это понятие вообще не привязанно к языку. Если в С нет классов, это не значит что полиморфизм там не возможен

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

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

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

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

Это называется "То ли я дурак, то ли лыжи не едут". =)
0
18822 / 9826 / 2401
Регистрация: 30.01.2014
Сообщений: 17,260
12.03.2014, 21:13 27

Не по теме:

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



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

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

Цитата Сообщение от Izual Посмотреть сообщение
Я для того и создал тему, чтобы найти инфу по инетересующему вопросу, тем более что как использовать в обычных условиях union это понятно. Но тут не тривиальный вопрос.
Считай, что ответ на твой вопрос - "нельзя". А куча встречных вопросов диктуется тем, что твой вопрос изначально является идиотским и люди хотят понять, ради чего разводится такой геморрой. Я, если честно, кроме экономии 5 букв ни одной разумной причины не понял
0
18822 / 9826 / 2401
Регистрация: 30.01.2014
Сообщений: 17,260
12.03.2014, 22:16 30

Не по теме:

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



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

Не по теме:

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



Цитата Сообщение от Izual Посмотреть сообщение
Нужна либо оптимизация
Убрать синтаксический оверхед возможно. То есть я реально знаю способ, который позволит задать 1-N типов в union и получить автоматически операторы преобразования для всех них без необходимости вручную прописывать каждый оператор. Но это потребует использования С++ и его возможностей (в частности шаблонов). При условии, что ты писал о неприемлемости использования "новомодных" фич языка, я этот пример приводить не стал. А если оставаться в рамках Си или упрощенного Си++, то без ручного (или полуручного с помощью макросов) перечисления всех возможных вариантов не обойтись никак. Что и демонстрируют все известные мне реализации вариантных типов. Это я имел в виду, когда писал
Цитата Сообщение от DrOffset Посмотреть сообщение
полноценной реализации вариантного типа, в котором было бы "мало" кода...
.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,511
12.03.2014, 22:19 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
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
12.03.2014, 22:25 32
Цитата Сообщение от ValeryS Посмотреть сообщение
ну наверно потому что он хочет конвертировать значения
Это всего лишь твоё предположение. Наличие char[20] явно говорит о том, что предположение некорректное. Первоначальное назначение union'а - это хранить разнотипные значения, а не конвертировать битовые образы значений (последнее, строго говоря, противоречит strict aliasing rules)
1
18822 / 9826 / 2401
Регистрация: 30.01.2014
Сообщений: 17,260
12.03.2014, 22:27 33

Не по теме:

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




Если текущий вопрос состоит именно в том, как он подан в его первом посте, то решение для него есть. Но оно не удовлетворит автора по религиозным причинам. Что еще предложить - лично я не знаю.
Могу привести код, если хотите.
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
12.03.2014, 22:56  [ТС] 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 Посмотреть сообщение
помогать людям
"благими намерениями дорога в ад вымощена"... почему - потому что есть ещё целый пласт знаний и этики, кому и как давать, и другие производные вопросы - потому не каждый может являться учителем(вот видите, у меня даже принимаемая информация от первого вашего поста уже не воспринялась, имею ввиду ссылку), ну это не беда, мы потому и в этом матерриальном мире - потому что эгоистичны и не приняли бога и его канонов(это так философия вед, чтоб вы не расстраивались, а извлекли урок и учтя его - не наступали дважды на грабли)
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
12.03.2014, 23:05 35
Цитата Сообщение от Izual Посмотреть сообщение
Люди выдумывают на ходу что хотят
Имеем два факта:

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

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

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

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

Не по теме:

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

0
18822 / 9826 / 2401
Регистрация: 30.01.2014
Сообщений: 17,260
13.03.2014, 01:56 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 работает почти везде. Однако это не дает повода утверждать, что он стандартен
0
elivin
13.03.2014, 08:03
  #39

Не по теме:

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

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

P.S. Персонально для Izual: вы первый начали лезть в узкое место торцевой части морского огурца. Если вам так претит любая, пусть даже и не абсолютно четко по теме, критика, то может не стоит вообще ни с кем разговаривать?
P.P.S. Персонально для Evg: ну хочется человеку сократить пять букв. Вы попробовали отговорить от того, что по вашему кажется не разумным - не получилось. Теперь можете либо помочь ему в этом, либо не помочь.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.03.2014, 10:17

Как можно удалить все элементы из List без указания диапазона и индекса?
че-то так не получается digit.Remove();

Обращение к переменной типа int в СУБД
Как обращаться к переменной типа int в СУБД в условии? Допустим с типом char вот так:...

Обратиться к переменной класса без указания самого класса
Вот код: using System; using System.Collections.Generic; using System.Linq; using System.Text;...

Сколько значений переменных типа char можно записать в динамической памяти на место одной удаленной переменной типа int
Сколько значений переменных типа char можно записать в динамической памяти на место одной удаленной...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru