如何访问"std::variant"的任何子级的"多态"基类?



假设一个基类有几个子类:

class Base 
{
public:
void printHello() const { cout << "Hello" << endl; }
};
class Child1: public Base {};
class Child2: public Base {};
class Child3: public Base {};
..
class ChildN: public Base {};

假设一个包含任何包含类的变体:

using MyVariant = std::variant<Base, Child1, Child2, Child3, ... ChildN>;

注意:这个的兴趣(与多态的简单向量相比 指针(,是将所有数据放在同一个内存数组中,因为 它们将被传输到设备。在这种情况下,真正的 每个对象的内容都在向量中,而不仅仅是指向某些对象的指针heap位置。

最后,假设我想使用vector<MyVariant>的每个元素的Base多态版本。

std::vector<MyVariant> myVariantList;
... // Initialization
for (const MyVariant& elem: myVariantList)
{
const Base* baseElem = get_if_polymorph<Base>(elem); //HOW TO?
baseElem->printHello();
}

注意:显然,为每个类型使用if语句的简单解决方案并不是本意,因为可以将新的子类添加到MyVariant而无需更改所有进一步的用法。(可扩展性(

所以表达这个问题的另一种方式是:

如何管理 std::variant 中的多态性?

std::visit与通用 lambda 一起使用:

const Base& baseElem = std::visit(
[](const auto& x) -> const Base& { return x; },
elem);

最小可重现示例:

#include <iostream>
#include <variant>
#include <vector>
struct Base {
virtual void hi() const
{
std::cout << "Basen";
}
};
struct Derived1 : Base {
void hi() const override
{
std::cout << "Derived1n";
}
};
struct Derived2 : Base {
void hi() const override
{
std::cout << "Derived2n";
}
};
int main()
{
using Var = std::variant<Base, Derived1, Derived2>;
std::vector<Var> elems;
elems.emplace_back(std::in_place_type<Base>);
elems.emplace_back(std::in_place_type<Derived1>);
elems.emplace_back(std::in_place_type<Derived2>);
for (const auto& elem : elems) {
const Base& x = std::visit(
[](const auto& x) -> const Base& { return x; },
elem);
x.hi();
}
}

输出:

Base
Derived1
Derived2

(现场演示(

最新更新