Каковы преимущества использования std :: варианте по сравнению с традиционной полиморфной обработкой? - PullRequest
0 голосов
/ 12 сентября 2018

Предположим, у меня есть Shape базовый класс и Circle, Line и Point производные классы.У меня есть две функции.

std::variant<Circle, Line, Point> process(const Shape &s);
Shape process(const Shape& s);

Я могу передать любой из моих производных классов и вернуть объект Shape во второй функции, вариант - это просто объединение, которое может содержать любую из моих переменных производного класса в любойзаданное время.

Теперь с std::variant я также могу использовать visitor, где я могу обработать некоторую функцию в зависимости от того, какой тип содержит мой вариант (я мог бы просто создать объект функции и передать его std::transform и применить его к каждому из моих объектов).Тем не менее, я могу просто сделать эту функцию virtual в своем базовом классе и сделать так, чтобы каждый производный класс ее реализовывал.

Итак, variant просто удобство?

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

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

Да .... если все элементы в variantразделяют общую базу (о которой Слава уже упоминал ).

Другое большое отличие состоит в том, что при variant необязательно любой динамический полиморфизм, происходящий вообще(RTTI не требуется) во время посещения.

В сочетании с std::visit под капотом есть много хитростей, обеспечивающих (в основном) нулевые издержки времени выполнения при вызове соответствующей функции для данной std::variant.Хотя может быть нетривиальное дополнительное время компиляции и использование памяти, потому что он делает это путем создания большой матрицы указателей на функции ( См. Это превосходное сообщение в блоге от Майкла Парк об этом)

0 голосов
/ 12 сентября 2018

Итак, вариант - это просто удобство?

Нет, это разные понятия. Основное отличие в том, что с одной стороны std::variant может работать с несвязанными типами, включая встроенные, например int, что невозможно для виртуальных функций напрямую. С другой стороны, std::variant должен знать типы, с которыми он работает во время компиляции. Например, можно добавить тип с помощью виртуальной функции (ей), просто связав дополнительный объектный модуль без перекомпиляции остальной части кода или динамической загрузки общей библиотеки в существующее приложение (вам даже не нужно перезапускать приложение), в то время как с std::variant Вы должны перекомпилировать код, относящийся к типам std::variant содержит.

...