【发布时间】:2021-06-18 14:17:59
【问题描述】:
我必须使用一个对象工厂来创建几种类型的新对象,每种类型都派生自多态基类。每个对象的类型都是事先知道的,但工厂返回基类上的指针。因此,在构造之后,我需要将该指针向下转换为特定对象类的类型。在大多数情况下static_cast 完美地完成了它的工作,但在虚拟继承的情况下dynamic_cast 必须用于向下转换。同时,由于运行时开销,我不想将dynamic_cast 用于从基类非虚拟继承的简单类型。
换句话说,我想找到或制作一个函数,如果它可用于此转换(例如,To 不是 实际上派生自From) 或dynamic_cast,否则。
预期用例:
template <typename To, typename From>
To fastest_cast( From && from );
struct A { virtual ~A() = default; };
struct B : A {};
struct C : virtual A {};
int main()
{
B b;
fastest_cast<B*>( (A*)&b ); //expected static_cast inside
C c;
fastest_cast<C*>( (A*)&c ); //expected dynamic_cast inside
}
在 std-library 或 boost-library 中是否有类似于 fastest_cast 的内容?还是需要自己实现转换功能(请指教)?
【问题讨论】:
-
这是一个有效的问题,可能有办法。但同样值得注意的是,如果您出于性能原因这样做,则可能会被误导。您正在牺牲
dynamic_cast(即运行时检查)的安全性来换取跳过它的感知效率。而且,在我看来,如果您非常担心转换类型的效率问题,那么您可能一开始就不应该在程序的那部分使用虚拟继承。 -
这不是降神会。
static_cast在代码中说:我知道它是什么类型,只是在编译时进行转换。dynamic_cast说:我怀疑这种类型会在运行时检查它。如果您需要这个奇怪的fastest_cast,您不了解差异,或者您在代码中做了一些奇怪的事情。 -
我不确定您为什么希望在第一种情况下使用 static_cast。不能保证
A*是B*,它可能是从 A 派生的其他类。 -
编译器可能已经优化了这个给定的静态分析。这应该很容易在 Godbolt godbolt.org 上验证
-
将
A*转换为C*时,static_cast表达式的格式明显不正确。 SFINAE 对此并不难。也可以在调试和发布模式下使其行为不同。如果您有良好的测试覆盖率,这可能不是一个毫无意义的冒险。
标签: c++ dynamic-cast static-cast virtual-inheritance