Подтвердить что ты не робот

Где использовать std:: variant over union?

Пожалуйста, объясните, в чем разница между union и std::variant и почему std::variant был введен в стандарт? В каких ситуациях мы должны использовать std::variant для старой школы union?

4b9b3361

Ответ 1

Вообще говоря, вы должны предпочесть variant, если не появится одно из следующих:

  • Вы обманываете. Вы делаете пиратство или другие вещи, которые являются UB, но вы надеетесь, что ваш компилятор не нарушит ваш код.

  • Вы выполняете некоторые псевдо-пунниры, разрешенные С++ union: преобразование между совместимыми с макетами типами или между общими начальными последовательностями.

  • Вам явно нужна тривиальная совместимость и/или совместимость макетов. variant<Ts> не требуется, чтобы какой-либо конкретный макет или тривиальная копируемость. unions стандартных типов макета - стандартная компоновка, а union тривиально-скопируемых типов тривиально можно копировать.

    Обратите внимание, что существует предложение сделать variant тривиально скопируемое, если его типы компонентов тривиально копируются. Он предложил в качестве отчета о дефектах против С++ 17, поэтому это поведение будет эффективно передано в С++ 17.

  • Вам нужна низкоуровневая поддержка для переключения объектов на месте. Использование буфера памяти для таких вещей не дает тривиальных гарантий копирования, которые вы могли бы получить из union.

Основное различие между ними состоит в том, что variant знает, какой тип он хранит, а union ожидает, что вы будете отслеживать это извне. Поэтому, если вы попытаетесь получить доступ к неправильному элементу в variant, вы получите исключение или nullptr. В отличие от этого, при использовании union это просто поведение undefined.

union - инструмент нижнего уровня, поэтому его следует использовать только тогда, когда вам абсолютно необходим этот уровень ниже.

variant также имеет механизм для посещения, а это означает, что вы избегаете наличия кучи операторов if, где вы спрашиваете "если это тип X, сделайте это. Если это тип Y, сделайте это и т.д.".