您的位置:首页 >C++类型擦除实现方法解析
发布于2026-02-17 阅读(0)
扫一扫,手机访问
答案是使用虚函数实现类型擦除的核心在于通过抽象基类定义统一接口,模板派生类封装具体类型,外部类持有基类指针以实现多态调用。示例中AnyFunction通过继承体系包装任意可调用对象,调用时无需知晓原始类型,从而实现类型无关的接口统一。

在C++中,类型擦除(Type Erasure)是一种让不同类型的对象表现出统一接口的技术,同时隐藏其具体类型。它常用于实现像 std::function、std::any 这样的通用容器。核心思想是将具体类型“擦除”,通过统一的接口调用底层操作。
最常见的方法是借助基类的虚函数机制,把具体类型封装到派生类中,对外暴露统一接口。
步骤:
示例:实现一个简易的任意可调用对象包装器
#include <iostream>
#include <memory>
#include <string>
// 抽象基类
struct FunctionBase {
virtual void call() const = 0;
virtual std::unique_ptr<FunctionBase> clone() const = 0;
virtual ~FunctionBase() = default;
};
// 模板派生类
template<typename F>
struct FunctionWrapper : FunctionBase {
F f;
FunctionWrapper(F f) : f(std::move(f)) {}
void call() const override {
f();
}
std::unique_ptr<FunctionBase> clone() const override {
return std::make_unique<FunctionWrapper>(f);
}
};
// 外部接口类,用户使用
class AnyFunction {
std::unique_ptr<FunctionBase> func;
public:
template<typename F>
AnyFunction(F f) : func(std::make_unique<FunctionWrapper<F>>(std::move(f))) {}
AnyFunction(const AnyFunction& other)
: func(other.func->clone()) {}
AnyFunction& operator=(const AnyFunction& other) {
func = other.func->clone();
return *this;
}
void operator()() const {
func->call();
}
};使用方式:
```cpp void hello() { std::cout << "Hello\n"; } int main() { AnyFunction f1 = [] { std::cout << "Lambda\n"; }; AnyFunction f2 = hello; f1(); // 输出 Lambda f2(); // 输出 Hello } ```避免虚函数开销,可以用函数指针+void* 来存储数据和操作函数。
原理: 将操作函数和数据指针绑定,运行时通过函数指针调用。
class SimpleFunction {
void* data = nullptr;
void (*call_func)(void*) = nullptr;
void (*copy_func)(void*, const void*) = nullptr;
public:
template<typename F>
SimpleFunction(F f) {
struct Storage {
F func;
static void call(void* p) {
static_cast<Storage*>(p)->func();
}
static void copy(void* dst, const void* src) {
new(dst) Storage(*static_cast<const Storage*>(src));
}
};
// 假设栈上分配或小对象内嵌(简化起见用new)
data = new Storage{std::move(f)};
call_func = &Storage::call;
copy_func = &Storage::copy;
}
void operator()() const {
call_func(data);
}
~SimpleFunction() {
// 实际需记录大小并调用析构,此处略
}
};这种方式更接近 std::function 的内部实现,支持小对象优化(SOO)时性能更好。
基本上就这些。类型擦除的关键是分离接口与实现,通过中间层屏蔽具体类型。用虚函数最直观,用函数指针+void* 更高效但实现复杂些。根据需求选择合适方式即可。
上一篇:搜狗浏览器网页版登录入口官网
下一篇:酷狗音乐官网入口及在线播放器
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9