Союзы, используемые как классы/структуры

Я пытался узнать больше об объединениях и их полезности, когда был удивлен, что следующий код совершенно корректен и работает точно так, как ожидалось:

template <class T>
union Foo
{
    T a;
    float b;

    Foo(const T& value)
        : a(value)
    {
    }

    Foo(float f)
        : b(f)
    {
    }

    void bar()
    {
    }

    ~Foo()
    {
    }
};

int main(int argc, char* argv[])
{
    Foo<int> foo1(12.0f);
    Foo<int> foo2((int) 12);

    foo1.bar();
    foo2.bar();

    int s = sizeof(foo1); // s = 4, correct

    return 0;
}

До сих пор я понятия не имел, что можно объявлять объединения с шаблонами, конструкторами, деструкторами и даже функциями-членами. Если это уместно, я использую Visual Studio 2012.

Когда я искал в Интернете, чтобы узнать больше об использовании союзов таким образом, я ничего не нашел. Это новая функция C++ или что-то специфичное для MSVC? Если нет, я хотел бы узнать больше об объединениях, в частности, о примерах их использования в качестве классов (выше). Если бы кто-нибудь мог указать мне на более подробное объяснение союзов и их использования в качестве структур данных, я был бы очень признателен.


person Zeenobit    schedule 08.08.2013    source источник
comment
Стандарт 2003 года, Союзы 9.5, пункт 1 "... A union can have member functions (including constructors and destructors), but not virtual (10.3) functions. ..." Так что не ново. Просто необычно. Что касается шаблонов, я не могу найти какой-либо специальной формулировки, но я почти уверен, что в этом отношении он рассматривается как class (точно так же нет специальной формулировки для structs).   -  person BoBTFish    schedule 08.08.2013


Ответы (1)


Это новая функция C++ или что-то специфичное для MSVC?

Нет, как сказал BoBtFish, в стандартном разделе С++ 2003 года 9.5 Unions параграф 1 говорится:

[...] Объединение может иметь функции-члены (включая конструкторы и деструкторы), но не виртуальные (10.3) функции. Объединение не должно иметь базовых классов. Объединение не должно использоваться в качестве базового класса. Объект класса с нетривиальным конструктором (12.1), нетривиальным конструктором копирования (12.8), нетривиальным деструктором (12.4) или нетривиальным оператором присваивания копирования (13.5.3, 12.8) не может быть членом объединения, равно как и массив таких объектов. Если объединение содержит статический элемент данных или член ссылочного типа, программа имеет неправильный формат.

union относятся к разделу 9 Classes, а грамматика для ключа класса выглядит следующим образом:

class-key:
   class
   struct
   union

So действует как class, но имеет гораздо больше ограничений. Ключевым ограничением является то, что unions может иметь только один активный нестатический элемент одновременно, что также рассматривается в параграфе 1:

В объединении не более одного из нестатических элементов данных может быть активен в любой момент времени, то есть значение не более одного из нестатических элементов данных может храниться в объединении. в любое время. [...]

Формулировка в C++11 draft standard похож, так что он не сильно изменился с 2003.

Что касается использования union, есть две распространенные причины, которые рассматриваются с разных сторон в этом предыдущем потоке C/C++: Когда кто-нибудь может использовать объединение? Является ли это в основном пережитком дней C? Подводя итог:

Этот ответ на Unions cannot be used as Base class дает действительно хорошее представление о том, почему unions реализованы именно так, как в C++.

person Shafik Yaghmour    schedule 11.08.2013