【发布时间】:2010-05-23 22:41:15
【问题描述】:
我想在编译时确定是否可以在没有 dynamic_cast 的情况下从指向 Base 的指针转换指向 Derived 的指针。这可能使用模板和元编程吗?这与确定 Base 是否是 Derived 的虚拟基类并不完全相同,因为 Base 可能是 Derived 的虚拟基类的超类。
谢谢, 蒂姆 更新: 我对这种方法感觉很好:
#include <iostream>
using namespace std;
class Foo
{
};
class Bar : public Foo
{
};
class Baz : public virtual Foo
{
};
class Autre : public virtual Bar
{
};
typedef char Small;
class Big { char dummy[2]; };
template<typename B, typename D>
struct is_static_castable
{
const B* foo;
char bar[1];
static Small test(char(*)[sizeof(static_cast<const D*>(foo)) == sizeof(const D*)]);
static Big test(...);
enum { value = (sizeof(test(&bar)) == sizeof(Small)) };
};
int main()
{
cout << "Foo -> Bar: " << is_static_castable<Foo, Bar>::value << "\n";
cout << "Foo -> Baz: " << is_static_castable<Foo, Baz>::value << "\n";
cout << "Foo -> Autre: " << is_static_castable<Foo, Autre>::value << "\n";
}
但它不适用于 gcc:
multi-fun.cpp: In instantiation of ‘is_static_castable<Foo, Baz>’:
multi-fun.cpp:38: instantiated from here
multi-fun.cpp:29: error: cannot convert from base ‘Foo’ to derived type ‘Baz’ via virtual base ‘Foo’
multi-fun.cpp:29: error: array bound is not an integer constant
multi-fun.cpp: In instantiation of ‘is_static_castable<Foo, Autre>’:
multi-fun.cpp:39: instantiated from here
multi-fun.cpp:29: error: cannot convert from base ‘Foo’ to derived type ‘Autre’ via virtual base ‘Bar’
multi-fun.cpp:29: error: array bound is not an integer constant
我是否对 sizeof() 技巧可以做什么感到困惑?
【问题讨论】:
-
我认为如果
Base只是Derived的虚拟基类的超类,这应该与static_cast一起使用。至少我找不到标准另有说明。您可以使用boost::is_virtual_base_of来检查其他情况。 -
我几乎可以想到一些方法,但它们很难看。如果你能给我一些关于你想用这个做什么的信息,我可能会想出一些东西。
-
如果 Base 是 Derived 的虚拟基的超类,gcc 会产生错误(例如):错误:无法从基 'osg::Referenced' 转换为派生类型 'osgViewer: :ViewerBase' via virtual base 'osg::Object' 使用虚拟基类是使用指向基的指针实现的心理模型,错误对我来说很有意义:static_cast 可以毫无问题地将“超级基”转换为虚拟基,但是在将指针转换为派生类型时情况相同。
-
@Tim 绝对不在这里:codepad.org/9cf7ZWK2
-
@litb 我的情况有点不同:codepad.org/MMlYcvJw。正如我所怀疑的那样,这不会编译。