You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现存储满足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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 01:08:18