Key points
继承中的多态:子类实现(implement)父类中定义的接口。
模板中的多态:不同的类遵守(conform to)相同的接口。
使用基于模板的多态的问题是caller也要是模板,即传染性。总的来说,有需要异质(heterogeneous)容器的需求;而一般的容器都要求元素是相同的类型(homogeneous)。
OO中的interface类比于template中的concept;OO中的interface和implement/instance类比于concept和model。
std::any是一个类(不是类模板),以type-safe的方式存is_copy_constructible类型的值。即只要类型conform to is_copy_constructible接口,它的值就能存在any对象里面。any擦除了任何is_copy_constructible类型的实际类型。
std::function是个类模板,它是一个function wrapper,可以存并调用任何CopyConstructible且Callable的target:function pointer,lambda expression,bind expression,function object/functor,pointer to member function(non-static/static,virtual/non-virtual),pointer to data member。function擦除了target的实际类型,而其模板参数表明了target应该conform to的函数原型。
尽管etl::delegate看上去和std::function很像,但是它没有使用类型擦除技术;是否有类型擦除,主要还是看它是存wrapper还是不是。
和CRTP的不同
Type Erasure实现了runtime polymorphism(但不依靠继承),CRTP(Curiously Recurring Template Pattern)实现了compile-time polymorphism(static dispatch或者policy-based design)。Type Erasure以性能换取弹性(trades performance for flexibility),CRTP以弹性换取性能(trades flexibility for performance),更强的type safety。
简单从表相上来看,Type Erasure是模板类继承自普通类,CRTP是普通类继承自模板类。
1 | // Type Erasure |
1 | // CRTP |
Examples
1 | class SeeAndSay { |
1 | class Object { |
1 | class Greeter { |