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

Visit a polymorphic type, like a variant without knowing the exact subtypes

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

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

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*>);
});

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

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

您可以使用 derived* test = dynamic_cast<derived*>(object) 来测试特定的子类型:如果 object 确实是 derived 那么 test 将是指向它的指针,但是,如果它实际上是 base 然后 test 将是 nullptr.

没有

按照描述解决问题需要runtime/dynamic link 模板代码的时间具体化。这是C++所缺乏的特性。

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

花哨的替代对象模型允许从实例中拆分 vtables 和 "RLE"-ing 缓冲区中的类型和类似的,但这也不会像你描述的那样。

TL;DR 仍然是 "No" 是你问题的答案,你不能那样做。


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

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

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

如果您有实际的具体问题,我鼓励您 post 提出有关它的问题而不是这种抽象。我的爱好是找到 SO post 的合理答案是 "no" 并提供不明智的 "yes" 答案。