LLVM是避免动态强制转换规则的例外吗?

时间:2009-10-23 00:53:29

标签: c++ design-patterns llvm dynamic-cast

LLVM拥有自己的RTTI替代方案,这是对内置RTTI的速度提升,并允许动态转换为没有vtable(dyn_cast)的类。但是,它仍然可以完全按照dynamic_cast<>的使用方式使用,尽管它允许它与更多类一起使用。

dyn_cast<> template documentation

LLVM是一个声誉良好的C ++项目,所以这似乎是在面对一个普遍的说法,即过多的动态转换是设计糟糕的标志,也称为代码气味。当然,表现更好的动态演员阵容无法改善其在设计中的使用,而不是标准dynamic_cast。那么谁在这里?在C ++代码中,是否存在大规模使用动态铸造是一个很好的设计选择的情况?谷歌在LLVM中继源代码中出现了690次这种动态转换。

Uses of dyn_cast<> in LLVM trunk

3 个答案:

答案 0 :(得分:7)

虽然性能匹配是避免大型类层次结构dynamic_cast<>的一个原因,但这并不是您可能想要避免它们的唯一原因。无论是否表现更好,都不应该因为这一主张而更加鼓励使用dyn_cast<>

另一方面,当dynamic_cast<>是最适合工作的工具时,使用dynamic_cast<>绝对没有错。如果它的使用是合理的,并且是解决问题的最简洁方法,那么无论“常见的说法”如何,它总是正确的。

我肯定不会仅仅因为使用goto s,{{1}}或任何其他不受欢迎的习惯用语而避开热门项目。

答案 1 :(得分:1)

我认为动态演员阵容很糟糕并不是因为它们很慢,而是因为它们暗示你的代码太紧密了。

答案 2 :(得分:-1)

我只是在LLVM文档中快速查看了dyn_cast和isa的实现。

代码中的例子如下:

struct bar {
  bar() {}
private:
  bar(const bar &);

};
struct foo {
  void ext() const;
  /*  static bool classof(const bar *X) {
    cerr << "Classof: " << X << "\n";
    return true;
    }*/
};

template <> inline bool isa_impl<foo,bar>(const bar &Val) {
  errs() << "Classof: " << &Val << "\n";
  return true;
}

使用B调用测试并具有:

if (!isa<foo>(B1)) return;
if (!isa<foo>(B2)) return;

如果我理解正确的是什么,isa模板(由dyn_cast使用)使用isa_impl的显式特化来将栏与foo链接起来。在给出的示例中,似乎isa<foo>(B1)返回true!

无论如何,这与dynamic_cast的行为完全不同,所以我真的不认为你可以将它们相互比较。

显然,我可能会误解LLVM正在做什么,所以如果我不理解代码,请告诉我!