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

Каковы различия между std:: variant и boost:: variant?

В ответ на этот так вопрос:

Что эквивалентно boost :: variable в стандартной библиотеке C++?

упомянуто, что boost::variant и std::variant несколько отличаются.

  • Каковы различия, когда кто-то использует эти классы?
  • Какую мотивацию выразил комитет для принятия std::variant с этими различиями?
  • На что следует обращать внимание при кодировании с одним из них, чтобы обеспечить максимальную совместимость с переключением на другое?

(мотивация заключается в использовании boost::variant в коде до C++ 17)

4b9b3361

Ответ 1

  • Поведение назначения/размещения:

    • boost::variant может выделять память при выполнении присваивания в живом variant. Существует ряд правил, определяющих, когда это может произойти, поэтому вопрос о том, будет ли boost::variant выделять память, зависит от Ts он создается.

    • std::variant никогда не будет динамически распределять память. Однако в качестве уступки сложным правилам объектов C++, если выбрасывает присваивание/размещение, variant может войти в состояние "valueless_by_exception". В этом состоянии variant недоступен, и никакие другие функции для доступа к конкретному члену не будут работать.

      Вы можете войти в это состояние, только если броски с назначением/назначением.

  • Boost.Variant включает в себя recursive_variant, который позволяет variant содержать себя. По сути, они являются специальными обертками вокруг указателя на boost::variant, но они связаны с механизмом посещения.

    std::variant нет такого вспомогательного типа.

  • std::variant option предлагает более широкое использование пост-C++ 11 функций. Например:

Ответ 2

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

variant<std::string, MyClassWithThrowingDefaultCtor> v = "ABC";
v = MyClassWithThrowingDefaultCtor();

Возможные варианты:

  • Предотвратите это, ограничив возможные отображаемые типы конструкциями, не допускающими переходов.
  • Сохраняйте старое значение - но для этого требуются двойные буферы (что, по-видимому, boost::variant).
  • Имейте "отключенное" состояние без значения для каждого варианта и переходите к этому состоянию при таких сбоях.
  • Undefined поведение
  • Сделайте вариант throw при попытке прочитать его значение после того, как произойдет что-то подобное

и если я не ошибаюсь, последнее - то, что было принято.

Это обобщено из блога ISO С++ post от Axel Naumann с ноября 2015 г.