Z
ZHANK
C++20/23 与惯用法

类型擦除

std::function 原理、AnyIterator 实现、虚函数+模板结合

类型擦除

类型擦除让不相关的类型"看起来一样"——std::function 是典型例子:任何可调用对象都能塞进同一个类型。

学完本章你将: 掌握 std::function 原理、AnyIterator 实现、虚函数+模板。


问题

cpp
// 想用同一个容器存不同函数类型?做不到——类型不同
std::function<int(int)> f1 = [](int x) { return x * 2; };
std::function<int(int)> f2 = [](int x) { return x + 1; };

std::vector<std::function<int(int)>> funcs = {f1, f2};
// ✅ 所有函数都擦除了原始类型,统一为 function<int(int)>

手写类型擦除

cpp
// 类型擦除的核心:外部接口 + 内部模板实现

class AnyDrawable {
    struct Concept {
        virtual ~Concept() = default;
        virtual void draw() const = 0;
        virtual std::unique_ptr<Concept> clone() const = 0;
    };

    template <typename T>
    struct Model : Concept {
        T obj;
        Model(T t) : obj(std::move(t)) { }
        void draw() const override { obj.draw(); }
        std::unique_ptr<Concept> clone() const override {
            return std::make_unique<Model>(obj);
        }
    };

    std::unique_ptr<Concept> ptr;

public:
    template <typename T>
    AnyDrawable(T obj) : ptr(std::make_unique<Model<T>>(std::move(obj))) { }

    void draw() const { ptr->draw(); }
};

💡 类型擦除以虚函数调用为代价(一次间接调用),换取类型统一和灵活性。