c++ - 在不知道确切子类型的情况下访问多态类型,例如变体

标签 c++ polymorphism type-erasure dynamic-dispatch

有时候知道多态对象的实际子类型是有益的——比如确保在我们重复调用虚函数的循环中不会发生虚调用。使 std::variant 可扩展到库的最终用户是一个巨大的痛苦,拥有一个接口(interface)要好得多。

理想情况下,我可以这样做:

struct base {
    virtual void foo() = 0;
};

struct derived : base {
    virtual void foo() override {}
};

// Sample
base* b = new derived{};
b->invoke_with_subtype([](auto* subtype) {
    static_assert(std::is_same_v<decltype(subtype), derived*>);
});

当然,生活并不那么理想,我需要以某种方式注入(inject)该功能。我在想某种 CRTP 技巧,但我一次又一次地遇到同样的问题,我就是无法删除传递的通用 lambda 函数。

TL;DR:是否可以在没有大量样板文件且事先知道所有子类型的情况下对多态类型进行动态分配?

最佳答案

没有。

如所述解决问题需要模板代码的运行时/动态链接时间具体化。这是 C++ 所缺乏的特性。

适度的限制消除了这种需求,但都需要权衡取舍。大多数需要某处受支持类型的列表,或受支持操作的列表。

花哨的替代对象模型允许从实例和缓冲区中的“RLE”类型中拆分 vtables 和类似的,但这也不会按照您的描述进行。

TL;DR 仍然是“否”是您问题的答案,您不能那样做。


SO 最适合解决具体的实际问题。根据我的经验,如果您有一个实际的实际用例,9/10 在您的实际用例中存在隐式限制,使您的问题可以解决。

相反,您生成了一个足以解决实际问题的抽象独立组。问题是您的抽象解决方案无法解决。

当然,像这样的 99/100 问题并没有解决实际的具体问题。

如果你有一个实际的具体问题,我鼓励你发布一个关于它的问题而不是这个抽象。我的爱好是寻找 SO 帖子,其明智的答案是“否”并提供愚蠢的"is"答案。

关于c++ - 在不知道确切子类型的情况下访问多态类型,例如变体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57631792/

相关文章:

c++ - 虚拟继承 : Error: no unique final overrider

java - 如何使用相同的父类(super class)方法初始化不同的子类类型?

c++ - 如何可靠地调用直接父级的虚函数

ios - 创建一个表示可以打开或关闭的可散列对象的协议(protocol)

c++ - FD_SET 问题/网络

c++ - 可变函数导致带有枚举的 SIGILL 信号

c++ - 使用 Cmake,如何防止库源包含在我的 IDE 中?

c# - 迷失在继承和多态中

c++ - boost::any 违反了 Liskov 替换原则

c++ - 获取 std::any 的大小