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

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

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Нужно разобраться с средой разработкой для C++ http://www.cyberforum.ru/cpp/thread1113231.html
Привет Всем ! Если я не ошибаюсь то с .NET 2003 (VS 7.1) шапки языка C++ немного изменился, и разница была следующая: 1. до: #include <iostream.h> void main(void) ...... и т.д... 2. после: #include <iostream>
C++ Libxl.h как подключить? Помогите подключить библиотеку к Visual C++ 2012 Или даже так - помогите разобраться с тем как парсить с xls файлов. http://www.cyberforum.ru/cpp/thread1111407.html
Ошибка с распределением цикла по потокам в Open MP C++
нужно цикл for разделить м/у потоками,но почему то ошибки выдает ,первый раз с Open MP работаю,подскажите как исправить ,пожалуйста... пишу на VS 2010 Ultimate ошибки:Ошибка 4 error C3004: shared: предложение не допускается в директиве OpenMP "for" Ошибка 5 error C3017: неверный вид проверки завершения в операторе For директивы OpenMP #pragma omp parallel { #pragma omp for...
Надзиратель томагавков или что за велосипед я изобрел? C++
She's alive! Господа, в общем вдохновился я темой programina про статические поля класса и решил создать что-то похожее на сборщик мусора. По скольку я придерживаюсь мнения, что порою лучше сперва самому поковыряться, а потом уже почитать как правильно надо было сделать, то вот такой у меня получился уродец. Долго думал куда можно его применить в качестве примера. Придумал - класс-томагавк....
C++ Получение из файла формата wav массива значений http://www.cyberforum.ru/cpp/thread1108824.html
Столкнулся со следующей задачей, требуется получить из wav файла массив значений. Сам владею Си на примитивном уровне, по этой причине решить данную задачу самостоятельно не могу, поиск в гугле ничего не дал (или просто я не увидел решения). Надеюсь на вашу помощь.
C++ Run exe from memory (x64) Есть необходимость запускать exe из памяти, а не с диска. Может кто сталкивался с данным проектом? Сам находил много проектов, но они были Win32 и не работали под сборкой x64. А мне нужен именно x64, так как это проект будет использоваться в связки с другими 64-битными проектами. подробнее

Показать сообщение отдельно
DrOffset
6917 / 4110 / 940
Регистрация: 30.01.2014
Сообщений: 6,906
13.03.2014, 01:56     Можно ли заменить обращение к Union без указания типа переменной?
Цитата Сообщение от 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 работает почти везде. Однако это не дает повода утверждать, что он стандартен
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru