当没有涉及到虚函数时,是否有办法将一个虚基类向下转换为派生类?以下是一些代码来演示我所说的:
struct Base1
{
int data;
};
struct Base2
{
char odd_size[9];
};
struct ViBase
{
double value;
};
struct MostDerived : Base1, Base2, virtual ViBase
{
bool ok;
};
void foo(ViBase &v)
{
MostDerived &md = somehow_cast<MostDerived&>(v); //but HOW?
md.ok = true;
}
int main()
{
MostDerived md;
foo(md);
}
请注意,此代码仅用于演示。我的实际场景相当复杂,涉及模板参数和从一个类型转换到另一个类型,只知道第一个类型是第二个类型的基类;它可以是普通基类或虚基类,并且可能具有虚函数或非虚函数。(在底部看到简化的示例)。我可以使用类型特征检测多态情况和虚/非虚基类情况,并解决除了非多态虚基类之外的所有问题。这就是我询问的内容。
我真的想不出如何进行转换:
- 隐式转换是不行的;它们只能进行向上转换。 - static_cast 明确禁止从虚基类进行转换: 5.2.9/2 ... 并且 B 既不是 D 的虚基类,也不是 D 的虚基类的基类。... - dynamic_cast 也无法完成,因为向下转换需要多态类 5.2.7/6 否则,v 必须是多态类型(10.3)的指针或 glvalue。 10.3/1 ... 声明或继承虚函数的类称为多态类。 - reinterpret_cast 在这里根本不适用。
如果 MostDerived 至少有一个虚函数,则当然可以使用 dynamic_cast 解决此问题。但是,当没有虚函数时,是否有办法进行转换?
(注意:所有引用都来自 C++11 草案 N3485)
鉴于评论过多地关注上面的示例代码,这里是我真实情况的简要说明:
template <class T_MostDerived>
struct Bar
{
template <class T_Base>
void foo(T_Base &b, typename std::enable_if<std::is_base_of<T_Base, T_MostDerived>::value>::type * = nullptr)
{
T_MostDerived &md = somehow_cast<T_MostDerived>(b);
do_stuff_with(md);
}
};
也就是说,我知道T_Base
是T_MostDerived
的基类(并且我知道T_MostDerived
实际上是最派生类型),但我对它们的其他信息一无所知;Bar
是我的代码,是库的一部分,未知的客户端可以使用。我可以检测到它是非多态虚基类,但在这种情况下我无法进行强制转换。
ViBase
成为多态的?(例如,你可以将其析构函数设为虚函数) - isekaijinvirtual
关键字。然后,将引用/指针重新解释为您现在处理的普通结构体,并愉快地进行操作... - AnonymousBase1
和Base2
与ViBase
无关,那么在这里使用virtual
继承会产生什么影响? - πάντα ῥεῖ