2013-08-08 3 views
4

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

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? Если нет, я хотел бы узнать больше об объединениях, в частности, примеры из них использовались как классы (см. Выше). Если кто-то может указать мне на более подробное объяснение профсоюзов и их использование в качестве структур данных, это было бы высоко оценено.

+1

2003 Стандарт, 9,5 Союзы, параграф 1 «... Союз может иметь функции-члены (включая конструкторы и деструкторы), но не виртуальные функции (10.3) ...» «Так что не новый. Просто необычно. Что касается шаблонов, я не могу найти какую-либо специальную формулировку, но я уверен, что в этом отношении она рассматривается как «класс» (точно так же нет специальной формулировки для 'struct'). – BoBTFish

ответ

2

Является ли это новой функцией C++ или что-то особенное для MSVC?

Нет, как сказал BoBtFish, 2003 C++ стандартный раздел 9.5 Unions пункт 1 говорит:

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

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

class-key: 
    class 
    struct 
    union 

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

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

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

Что касается использования union, есть две общие причины, которые покрыты под разными углами в этой предыдущей теме C/C++: When would anyone use a union? Is it basically a remnant from the C only days? подведем итоги:

  • Чтобы реализовать свой собственный Variant type, union дает возможность представлять все различные типы без потери памяти. This answer в теме дает хороший пример.

  • Type punning, но я читал Understanding Strict Aliasing, а так как есть много случаев, когда type punning является undefined behavior.

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

Смежные вопросы