一、插件系统
你写了一个事件处理系统,允许用户注册回调处理事件。你不想强制用户继承 EventHandler 接口:
class EventBus {
std::vector<std::function<void(const Event&)>> handlers_;
public:
void register(std::function<void(const Event&)> handler) {
handlers_.push_back(std::move(handler));
}
void fire(const Event& evt) {
for (auto& h : handlers_) h(evt);
}
};
// 用户不需要继承任何东西,传个 lambda 就行
EventBus bus;
bus.register([](const Event& e) { /* 处理 */ });
二、什么时候用 Type Erasure,什么时候用 variant?
如果你在编译期知道所有可能的类型:
用 std::variant<Circle, Square> ← 更快,没有虚函数调用
如果你要在运行时支持任意新类型:
用 Type Erasure ← 灵活,但有一次虚函数调用
如果你要让用户不需要改继承关系:
用 Type Erasure ← 非侵入式