如何实现存储满足Foo concept的不同类型对象的vector?
实现存储满足Concept的异构对象容器
步骤1:定义抽象接口类
首先需要一个抽象基类,它包含你需要从所有满足Foo概念的类型中调用的操作。比如如果Foo要求有do_something()方法,接口里就要声明对应的纯虚函数:
class FooInterface { public: virtual ~FooInterface() = default; // 必须声明虚析构,确保子类对象能正确销毁 virtual void do_something() = 0; // 对应Foo概念约束的核心操作 // 可根据Foo的其他约束添加更多纯虚函数 };
步骤2:实现类型擦除的包装类
写一个模板包装类,继承自FooInterface,用来持有任意满足Foo概念的对象,并将接口方法转发给实际对象:
template<Foo T> class FooWrapper : public FooInterface { private: T m_obj; // 存储实际对象,若对象体积大或需动态分配,可改用std::unique_ptr<T> public: explicit FooWrapper(T obj) : m_obj(std::move(obj)) {} void do_something() override { m_obj.do_something(); // 转发调用实际对象的方法 } // 其他Foo约束对应的方法,同样在这里做转发实现 };
步骤3:创建并使用容器
现在可以用std::vector<std::unique_ptr<FooInterface>>来存储所有满足Foo的不同类型对象了:
// 示例Foo概念定义 template<typename T> concept Foo = requires(T t) { { t.do_something() } -> std::same_as<void>; }; // 满足Foo的类型1 struct Bar { void do_something() { std::cout << "Bar doing something\n"; } }; // 满足Foo的类型2 struct Baz { void do_something() { std::cout << "Baz doing something\n"; } }; std::vector<std::unique_ptr<FooInterface>> getFooVector() { std::vector<std::unique_ptr<FooInterface>> vec; vec.emplace_back(std::make_unique<FooWrapper<Bar>>(Bar{})); vec.emplace_back(std::make_unique<FooWrapper<Baz>>(Baz{})); return vec; } // 使用示例 int main() { auto vec = getFooVector(); for (auto& ptr : vec) { ptr->do_something(); } return 0; }
关键注意点
- 抽象接口是核心:它定义了所有
Foo类型必须对外暴露的操作,是实现类型擦除的基础。 - 模板包装类做适配:
FooWrapper将任意满足Foo的类型适配到统一的FooInterface接口,完成类型擦除。 - 必须有虚析构:保证容器销毁时,能逐层调用子类的析构函数,避免内存泄漏。
如果你的Foo概念包含更多约束(比如不同的方法、返回值),只需在FooInterface中添加对应的纯虚函数,再在FooWrapper中补充转发逻辑即可。
内容的提问来源于stack exchange,提问作者Zach Clayburn
相关产品推荐
相关产品推荐

