Что представляют собой Неограниченные союзы, предложенные в С++ 11?

Я собираю unrestricted unions как одну из функциональных возможностей, представленных на С++ 11. Может ли кто-нибудь объяснить семантику за этим и преимуществами, которые она предоставляет?

Ответ 1

В Википедии есть объяснение: http://en.wikipedia.org/wiki/C%2B%2B0x#Unrestricted_unions

Искать там сначала, прежде чем спрашивать о возможностях С++ 0x.

Неограниченные союзы

В стандартном С++ существуют ограничения на то, какие типы объектов могут быть членами объединения. Например, профсоюзы не могут содержать никаких объекты, которые определяют нетривиальную конструктор. С++ 0x облегчит некоторые этих ограничений, позволяющих профсоюзам для использования на других типах, которые они ранее не разрешалось использовать на. [6] Это простой пример разрешено в С++ 0x:

//for placement new
#include <new>

struct Point  {
    Point() {}
    Point(int x, int y): x_(x), y_(y) {}
    int x_, y_;
};
union U {
    int z;
    double w;
    Point p;  // Illegal in C++; point has a non-trivial constructor. 
              //   However, this is legal in C++0x.
    U() { new( &p ) Point(); } // No nontrivial member functions are
                               //implicitly defined for a union;
                               // if required they are instead deleted
                               // to force a manual definition.
};

Изменения не нарушат существующий код, поскольку они только расслабляют текущие правила.

Ответ 2

Это не что иное, как старые союзы, которые мы всегда имели, объект, содержащий один член за раз, различного типа.

Это изменение заключается в том, что теперь вы можете хранить не-POD-типы в объединении. Тем не менее, вы будете отвечать за явное конструирование и уничтожение этого элемента.

Из N3242:

[Пример: Рассмотрим объект u типа объединения U, который имеет нестатические данные члены m типа M и n типа N. Если M имеет нетривиальный деструктор и N имеет нетривиальный конструктор (например, если они объявляют или наследуют виртуальные функции), активный член u можно безопасно переключать от m до n, используя деструктор и новый оператор размещения следующим образом:
u.m. ~ М();
new (& u.n) N; -end пример]

Не очень полезная функция, IMO.

Ответ 3

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

Цена, которую вы платите за это, заключается в том, что вам нужно сделать тщательный учет книг. С простым старым назначением объединения данных было достаточно, чтобы изменить "текущий тип", и чтение неправильного типа, скорее всего, приведет к искаженным данным, но не намного больше. С помощью несложного старого объединения данных вы должны следить за текущим типом и вызывать конструкторы и деструкторы corect вручную, чтобы изменить текущий тип и правильно очистить вещи при уничтожении объединения в целом. Если вы попытаетесь прочитать или записать тип скручивания, вероятно, произойдет что-то плохое.