Я собираю unrestricted unions
как одну из функциональных возможностей, представленных на С++ 11. Может ли кто-нибудь объяснить семантику за этим и преимуществами, которые она предоставляет?
Что представляют собой Неограниченные союзы, предложенные в С++ 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 вручную, чтобы изменить текущий тип и правильно очистить вещи при уничтожении объединения в целом. Если вы попытаетесь прочитать или записать тип скручивания, вероятно, произойдет что-то плохое.