我正在使用llvm库,我想检查llvm :: Value *是否实际上是llvm :: LoadInst *(llvm :: LoadInst继承自llvm :: Value)。
但遗憾的是,llvm :: Value并不包含任何虚拟方法! (是的,即使没有虚析构函数)是否可以在没有虚方法的类上使用dynamic_cast
,还是有其他方法可以进行类型检查?
答案 0 :(得分:3)
在LLVM中,有一个llvm::dyn_cast<T>
将使用LLVM的内部构造从一种类型动态转换为另一种类型,只要它们确实是有效的转换 - 如果你使用了错误的类型T
,它将返回nullptr
。
类似于:
llvm::Value *v = ... some code here ...
...
llvm::LoadInst* li = llvm::dyn_cast<llvm::LoadInst>(v);
if (!li) { ... not a LoadInst, do whatever you should do here ... }
else { ... use li ... }
当然,如果您已经知道v
是LoadInst
,那么您无需检查 - 但如果您遇到错误,assert(li && "Expected a LoadInst");
会抓住。
请注意,{C }+标准T*
不会llvm::dyn_cast<T>
使用dynamic_cast
。
llvm::Value
代码中的这条评论解释说,由于这个原因,没有完整的vtable(http://www.llvm.org/doxygen/Value_8h_source.html#l00207)
/// Value's destructor should be virtual by design, but that would require
/// that Value and all of its subclasses have a vtable that effectively
/// duplicates the information in the value ID. As a size optimization, the
/// destructor has been protected, and the caller should manually call
/// deleteValue.
~Value(); // Use deleteValue() to delete a generic Value.
答案 1 :(得分:1)
是否可以在没有虚拟方法的类上使用
dynamic_cast
如果输入不是指针或对多态类型的引用,则无法使用dynamic_cast
,即没有任何virtual
成员函数。
还是有其他方法可以进行类型检查吗?
我想不到任何。您最好的选择是使用static_cast
但是您必须非常确定您要投射的类型是有效的。
struct Base { ... };
struct Derived1 : Base { ... };
struct Derived2 : Base { ... };
void foo(Base* base)
{
Derived1* ptr = static_cast<Derived1*>(base);
// Use ptr
}
void bar()
{
foo(new Derived1()); // OK.
foo(new Derived2()); // Not OK since foo assumes that the pointer
// really points to a Derived1 object.
}