假设基类有几个子类:
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
位置。
最后,假设我想使用Base
的每个元素的vector<MyVariant>
多态版本。
std::vector<MyVariant> myVariantList;
... // Initialization
for (const MyVariant& elem: myVariantList)
{
const Base* baseElem = get_if_polymorph<Base>(elem); //HOW TO?
baseElem->printHello();
}
注:显然,对于每种类型使用
if
语句的简单解决方案是not意图,因为可以将新的子类添加到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 << "Base\n";
}
};
struct Derived1 : Base {
void hi() const override
{
std::cout << "Derived1\n";
}
};
struct Derived2 : Base {
void hi() const override
{
std::cout << "Derived2\n";
}
};
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