与传统的多态处理相比,使用 std::variant 有什么优势?

What are the advantages of using std::variant as opposed to traditional polymorphic processing?

假设我有一个 Shape 基础 class 和 CircleLinePoint 派生的 classes。我有两个功能。

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

我可以在第二个函数中传入我派生的任何 classes 和 return 一个 Shape 对象,变体只是一个联合体,它可以包含我派生的任何 class 任何给定时间的变量。

现在使用 std::variant 我还可以使用 visitor 来处理一些函数,具体取决于我的变体当前持有的类型(我可以创建一个函数对象并传递它 std::transform 并将其应用于我的每个对象)。但是,我可以在我的基础 class 中创建该函数 virtual 并让每个派生 class 实现它。

那么,variant 只是为了方便吗?

So, is variant just a convenience?

不,它们是不同的概念。主要区别在于,一方面 std::variant 可以使用不相关的类型,包括像 int 这样的内置函数,这不能直接使用虚函数。另一方面 std::variant 必须知道它在编译时使用的类型。例如,可以通过链接额外的对象模块来添加具有虚函数的类型,而无需重新编译其余代码或将共享库动态加载到现有应用程序(您甚至不必重新启动应用程序),同时使用 std::variant 您必须重新编译处理类型 std::variant 包含的代码。

However, I can just make that function virtual in my base class and have each derived class implement it.

是....如果 variant 中的所有元素共享一个公共基础()。

另一个很大的区别是,对于 variant,在访问期间根本没有必要 任何 动态多态性发生(不需要 RTTI)。

std::visit 相结合,有很多技巧可以确保在为给定的 std::variant 调用适当的函数时(基本上)运行时开销为零。虽然可能会有不平凡的额外编译时间和内存使用,因为它是通过创建一个大的函数指针矩阵来实现的(See this excellent blog post from Michael Park 关于它)