Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Отличие union от class/struct в C++98/C++03?  (Прочитано 14817 раз)
0 Пользователей и 5 Гостей смотрят эту тему.
oktonion
Постоялец

ru
Offline Offline

« : 22-06-2019 11:33 » 

C++ standard (§9.5.1)
Цитата
A union can have member functions (including constructors and destructors), but not virtual functions.
A union shall not have base classes. A union shall not be used as a base class.
An object of a class with a non-trivial constructor, a non-trivial copy-constructor, a non-trivial destructor, or a non-trivial copy assignment operator cannot be a member of a union, nor can an array of such objects.
If a union contains a static data member, or a member of a reference type, the program is ill-formed.

Какие еще отличия есть у union от class/struct в C++98/C++03?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 23-06-2019 16:42 » 

oktonion, а какие нужно ?

и вообще, union - это костыль, который нужен очень очень редко, обычно для работы с не очень хорошо спроектированной железякой. И совать туда какие-то хитрости вообще не советую.
Записан

RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 23-06-2019 18:07 » 

Не обязательно — железякой. Просто переиспользование памяти разными типами. Другой вопрос, что "нетривиальные" типы не поддерживаются. Редко бывает, но нужно.
Хороший пример — различные реализации std::string, использующие память структуры для хранения коротких строк, а для сдлинных строк таже память используется для указателя и сопутствующих данных.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
oktonion
Постоялец

ru
Offline Offline

« Ответ #3 : 23-06-2019 22:10 » 

Алексей++, хороший вопрос. На самом деле любые.
Поясню - хочу определять переданный шаблонный параметр union или class на этапе компиляции. В C++11 для этого ввели std::is_union и std::is_class соответственно, в 98/03 стандарте этого конечно нет. Все мои попытки на основе выдержки из стандарта отличить данные два понятия потерпели неудачу. union и class на столько похожи что у меня руки опускаются. Вот решил призвать коллективный мозг - возможно есть еще какое-то хитрое отличие, на основе которого я смогу вывести к чему относится тип.

Boost не предлагать. Там все тоже печально на эту тему.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 23-06-2019 23:30 » 

Следующий вопрос: а зачем? Что будем меняться для union и class?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 24-06-2019 07:37 » 

RXL, ну я под железякой как раз и имею в виду всякие трюки и их наследие (как и в CDBVariant тоже)

oktonion, в новые стандарты ввели флаги, чтобы было проще разбираться в старом коде. Но всё же лучше избегать union, на мой взгляд.

Если уж прям вообще никак не обойти (а это ещё надо уточнить), то оберни экземпляр твоего union в класс-контейнер, а в этот контейнер добавь флажок в виртуальной функции - isUnion(). Может, и без виртуальности получится, если у тебя шаблоны
Записан

oktonion
Постоялец

ru
Offline Offline

« Ответ #6 : 24-06-2019 14:15 » 

Следующий вопрос: а зачем? Что будем меняться для union и class?
Странный вопрос немного. К примеру от union отнаследоваться нельзя будет.


oktonion, в новые стандарты ввели флаги, чтобы было проще разбираться в старом коде. Но всё же лучше избегать union, на мой взгляд.

Если уж прям вообще никак не обойти (а это ещё надо уточнить), то оберни экземпляр твоего union в класс-контейнер, а в этот контейнер добавь флажок в виртуальной функции - isUnion(). Может, и без виртуальности получится, если у тебя шаблоны

Код чужой. Моего union там нет, там есть вражеский тип с которым нужно корректно работать. Я ничего о вражеском типе не знаю, потому и необходимо определять что за зверь.

Но мы как-то от темы вопроса отклоняемся.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 24-06-2019 22:39 » 

Ну и отлично, ошибка компиляции.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 25-06-2019 04:42 » 

oktonion, от темы вовсе не отклоняемся

но всё ещё непонятен вопрос: если о типе ничего не знаешь, как ты будешь с ним работать ? Ну а если знаешь о нём, что его нужно всячески оберегать - это по любому нужно обёртку делать

давай какую-то конкретно возникшую проблему с этим кодом опиши
Записан

RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 25-06-2019 07:14 » 

Да, пример было бы очень интересно увидеть. Мне еще не разу не встречался union как конечный тип, всегда в struct его прячут.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
oktonion
Постоялец

ru
Offline Offline

« Ответ #10 : 25-06-2019 10:58 » 

oktonion, от темы вовсе не отклоняемся

но всё ещё непонятен вопрос: если о типе ничего не знаешь, как ты будешь с ним работать ? Ну а если знаешь о нём, что его нужно всячески оберегать - это по любому нужно обёртку делать

давай какую-то конкретно возникшую проблему с этим кодом опиши

Вот я об этом отклонении и говорю. У меня вопрос - как определить что передан union как шаблонный параметр. У вас речь про "конкретную проблему с этим кодом". Нет проблемы с кодом у меня, у меня есть проблема определить что тип - union =) Я - автор библиотеки, а для чего там пользователь будет использовать is_union - его дело.

Как синтетический пример использования можно выдумать вот такое:
Код: (C++)
template<class T, bool TCanBeParent = std::is_class<T>::value, bool TIsUnion = std::is_union<T>::value>
struct SuperStruct;

template<class T>
struct SuperStruct<T, true, false>:
    public T
{
    using T::set;
};

template<class T>
struct SuperStruct<T, false, false>:
    public T
{
    void set(const T &value_) {value = value_;}
private:
    T value;
};

template<class T>
struct SuperStruct<T, false, true>:
    public T
{
    template<class TT>
    void set(const TT &value_) {obj.set(value_);}
private:
    T obj;
};

 

Но, повторюсь, проблемы с данным кодом у меня нет. У меня есть проблема с определением union на этапе компиляции.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 25-06-2019 11:14 » new

oktonion, Берём твой первый пост

Цитата
A union shall not be used as a base class.

делаем тест

Код: (C++)
//это класс, который хотим протестировать
union my_union
{
};

//это оболочка для классов-тестеров.(можно и без неё, впрочем)
struct test_class
{
        //...но для строгости делаем невозможным использование тестеров в общем коде
private:

        //тестер №1 - класс не скомпилируется, если my_union является union
        struct tester1:public my_union
        {
        };
};


Чтобы разрешить использовать таки union, придётся заставить пользователя использовать шаблон с другим именем, который будет уметь работать с union (интересно, что он там такое будет делать? )

Но какое-то это сильное усложнение. Лучше написать в описании - "не советую использовать union" Отлично
« Последнее редактирование: 25-06-2019 11:24 от Алексей++ » Записан

oktonion
Постоялец

ru
Offline Offline

« Ответ #12 : 25-06-2019 14:39 » 

Эх. Это и так понятно. А что на счет моего вопроса то? =)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 25-06-2019 15:43 » 

oktonion, ответ, видимо, такой: до C++11 нет штатного способа. И искать какую-то магию тут бесполезно
Записан

oktonion
Постоялец

ru
Offline Offline

« Ответ #14 : 25-06-2019 16:11 » 

oktonion, ответ, видимо, такой: до C++11 нет штатного способа. И искать какую-то магию тут бесполезно

То что штатного способа нет это тоже понятно, ведь в этом вся суть.
Вопрос в том какие еще отличия, кроме приведенной цитаты, есть у union и class?
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 26-06-2019 14:39 » 

Цитата
У меня вопрос - как определить что передан union как шаблонный параметр. У вас речь про "конкретную проблему с этим кодом". Нет проблемы с кодом у меня, у меня есть проблема определить что тип - union =) Я - автор библиотеки, а для чего там пользователь будет использовать is_union - его дело.
Ну раз это ваша библиотека, то вопрос в том, что она вообще такого будет делать с типами, как она их использовать планирует. Например, не очень понятно, зачем библиотеке может понадобиться наследоваться от пользовательского типа. Как параметр шаблона ещё ладно, но как можно построить специализацию в виде потомка для типа, чьё устройство и назначение заведомо неизвестны?
Записан
oktonion
Постоялец

ru
Offline Offline

« Ответ #16 : 30-06-2019 10:20 » 

Вад,
https://forum.shelek.ru/index.php/topic,31224.msg305182.html#msg305182 - мой пример
https://stackoverflow.com/a/23870545/6419156 - общее применение
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines