类型擦除通过封装具体类型,使不同类型的对象能以统一接口操作,如my_function包装函数和lambda,实现异构对象的同质处理。
类型擦除(Type Erasure)在C++中是一种技术,用于隐藏具体类型信息,使不同类型的对象能以统一接口操作。它常用于实现泛型容器或回调机制,比如 std::function 和 std::any 就是标准库中类型擦除的典型例子。核心思想是:把类型相关的差异“擦掉”,通过多态或内部封装暴露一致的行为。
C++模板虽然强大,但每个实例化都产生独立类型。这意味着 std::vector 和 std::vector 是完全不同的类型,无法直接用同一指针或引用管理。如果想让一个容器持有多种可调用对象(如函数、lambda、绑定表达式),就必须抹去它们的具体类型。
类型擦除解决了这个问题——它允许你在不知道具体类型的情况下调用其方法或执行其行为,同时保持值语义和性能可控。
以实现一个简易版的函数包装器为例,模拟 std::function 的基本原理:
然后我们提供一个外层包装类,对外隐藏类型细节:
class my_function { std::unique_ptr使用方式如下:
void func() { std::cout这里,f1 和 f2 虽然封装了不同类型对象,但具有相同类型 my_function,实现了类型擦除。
直接使用模板只能在编译期确定所有类型,不能动态存储异构对象。而类型擦除结合运行时多态,提供了更大的灵活性。
类型擦除本质是在性能和灵活性之间做权衡。
std::any 使用类型擦除实现。例如:
std::vector<:function>> tasks; tasks.emplace_back([]{ std::cout这个 vector 存储了完全不同类型的可调用对象,却能统一执行。
基本上就这些。类型擦除不是魔法,而是将模板的强大能力与面向对象的设计结合起来的一种实用技巧。理解它有助于深入掌握 C++ 泛型编程的本质。