2016-10-23 13 views
12

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

What is the equivalent of boost::variant in the C++ standard library?

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

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

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

+0

@JohnZwinck: Оценил ваш комментарий/ответ, видя, как вы написали, что ответ я связан. – einpoklum

+5

Я думаю, что JohnZwinck не получит уведомление, если он не взаимодействует с этим вопросом. Вместо этого вы можете прокомментировать его ответ на другой вопрос, чтобы привлечь его внимание. – DavidW

ответ

3

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

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

вариантов кажется:

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

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

Это суммируется из ISO C++ блог post Аксель Науманн с ноября 2015.

13
  • поведения Назначение/заложения:

    • boost::variant может allocate memory when performing assignment в живую variant. Есть a number of rules that govern when this can happen, поэтому независимо от того, будет ли boost::variant выделять память, зависит от Ts, в котором он был создан.

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

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

  • Boost.Variant включает в себя recursive_variant, который allows a variant to contain itself. Они по сути являются специальными обертками вокруг указателя на boost::variant, но они привязаны к механизму посещения.

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

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

    • Он пересылает noexcept статус специальных функций членов составляющих его типов.

    • Он имеет конструкторы на месте и на основе шаблонов на основе шаблонов.

    • Дефектные разрешения applied to C++17 may mean that it will also forward trivial copyability of its types. То есть, если все типы тривиально можно копировать, тогда также будет variant<Ts>.

+0

Можно ли добавить эту функцию рекурсивности в 'std :: variant' без изменения класса? (Но, возможно, с добавлением материала в 'namespace std'?) – einpoklum

+0

@einpoklum: точкой' recursive_variant' является то, что он позволяет 'visit' автоматически распаковывать и посещать объект, который он ссылается. Поэтому вам нужно будет построить этот механизм в 'std :: visit'. Это невозможно без * замены * 'std :: visit', чего вы не можете сделать. Конечно, вы всегда можете сделать свою собственную версию 'std :: visit' в своем собственном пространстве имен, что делает распаковку/посещение. –

+0

Интересно, добавляет ли он, что «рекурсивный_вариант» в версию 'std' добавляет« рекурсивный_вариант »... по крайней мере, теперь, когда я сильно использую варианты, кажется, что они могут сделать их рекурсивными, представляют большую часть их силы. –

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

  • Нет связанных вопросов^_^