在C ++中键入擦除解释

2021-04-16 00:52:01

您已经听说过C ++的类型擦除。您可能知道std ::函数是模式的经典用法。但是C ++中的类型擦除是什么?它有效地尝试实现鸭键入,这是Python这样的语言常见的。

#请注意,Bar1或Bar2class Bar1:def dosomething():print(" bar1")class bar2:def dosomething():print(" bar2" )def foo(bar):#wore in _any_栏上有`dosomething()`定义的bar.dosomething()foo(bar1())foo(bar2())

如果我们不上文类型安全,我们需要一个接口定义。描述了对论证的期望的东西。例如它具有定义了一种包含的剂量方法。简单的。

类摘录栏{虚拟void dosomething()= 0; Virtual〜AbstractBar()=默认值; //始终具有虚拟析构函数}; void foo(摘录栏和amp; bar);

现在,Foo采用从摘录栏课程继承的任何条形图。这意味着我们需要制作Bar1和Bar2从抽象栏继承,它可以非常快速地从手中旋转(每个接口的一个父类)。更不用说Bar1和Bar2可以在我们可以' t改变的第三方库中定义。

这一点的缺点是,现在作为一个库,您将您的实现公开给所有用户(由于模板),如果有很多呼叫,则它会减慢编译时间(有时剧烈地)。这里没有删除的类型&#39。不是我们想要的鸭子。我们希望实际捕获/删除类型t。例如。我们希望有一个我们可以称呼的东西的向量,他们可以有不同的行为(不同的底层类型)。

什么'锤子可以解决计算机科学中大多数问题的锤子?是的,另一个间接程度。

班级栏:公共摘录栏{public:模板< typename t>栏(t t){} void dosomething()覆盖{t_.dosomething(); //嗯......但是我们如何存储t_}}; void foo(栏杆);

如果我们有一个具有模板构造函数的栏级,它可以捕获/删除T型,如果我们制作纸条的一个似乎解决问题的抽象子类。不太好。我们需要存储T型T,只能使用模板类别完成。

模板< typeName t>类Barwrapper:公共摘录栏{public:显式barwrapper(t t):t_(t){} void dosomething()覆盖{t_.dosomething(); //这里没有VTABLE查找}私有:T T _;};类栏{PUBLIC:模板< typeName t>栏(t t){//类型捕获/删除此处t_ = std :: make_unique< barwrapper< t>(t); void dosomething(){t _-> dosomething(); // vtable查找在这里}私有:std :: unique_ptr<摘录栏和gt; T_; //现在我们解决了在不知道t}的情况下存储t_的问题; void foo(酒吧吧);

那个'很多间接级别。但结果很漂亮。 Void Foo(酒吧酒吧),它接受任何提供剂量的东西(在C ++中键入的鸭子)。当Bar1转换为栏时,它的类型被删除了。我们可以拥有STD :: Vector< bar>只要他们能够负担得起的手动行动,它就会储蓄不同的东西,并且它会在您期望的时候工作。

我学到了关于来自作者O&#39的类型擦除; dwyer' s post - https://quxplusone.github.io/blog/2019/03/18/what-is-type-erasure/我也强烈推荐他的帖子和CPPCONF视频。