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

无拷贝/移动构造函数时编译期添加成员的实现方案

实现方案与可行性分析

你的需求完全可以实现,核心思路是利用可变参数模板结合std::tuple在编译期确定所有Foo实例的类型与数量,全程无需动态分配或指针,所有对象都作为Pool的成员直接存储。

完整实现代码

#include <tuple>
#include <array>
#include <utility> // 用于std::forward和std::apply

class I_Foo
{
public:
    virtual void Do() = 0;
    virtual ~I_Foo() = default;
};

template <int a, int b>
class Foo : public I_Foo
{
public:
    explicit Foo(int x) : m_x {x} {}
    Foo(const Foo &) = delete;
    Foo(Foo&&) = delete; // 显式删除移动构造,避免隐式生成问题
    Foo & operator=(const Foo &) = delete;
    Foo& operator=(Foo&&) = delete;
protected:
    void Do() override { /* 自定义实现 */ }
private:
    static constexpr std::size_t k_ArraySize {a * b};
    std::array<int, k_ArraySize> m_Array {};
    int m_x;
};

template<typename... FooTypes>
class Pool
{
public:
    // 接收每个Foo的构造参数,就地构造所有实例
    template<typename... CtorArgs>
    explicit Pool(CtorArgs&&... args) 
        : m_foo_instances(std::forward<CtorArgs>(args)...) {}

    // 批量调用所有Foo的Do()方法(利用折叠表达式)
    void execute_all() {
        std::apply([](auto&... foo) {
            (foo.Do(), ...); // 折叠表达式遍历每个Foo实例调用Do()
        }, m_foo_instances);
    }

    // 获取指定索引的Foo实例(编译期索引)
    template<std::size_t Index>
    auto& get() {
        return std::get<Index>(m_foo_instances);
    }

    template<std::size_t Index>
    const auto& get() const {
        return std::get<Index>(m_foo_instances);
    }

private:
    // 用tuple存储所有Foo实例,编译期确定大小,无动态分配
    std::tuple<FooTypes...> m_foo_instances;
};

// 使用示例
int main() {
    // 直接传递每个Foo的构造参数,Pool会就地构造实例
    Pool<Foo<1,2>, Foo<3,2>> pool {1, 2};
    
    // 调用第一个Foo的Do()
    pool.get<0>().Do();
    // 批量调用所有Do()
    pool.execute_all();
    
    return 0;
}

关键细节说明

  • 规避拷贝/移动限制:由于Foo删除了拷贝构造,我们直接通过Pool的构造函数传递每个Foo的构造参数,让std::tuple就地构造所有实例,完全绕开拷贝/移动操作。
  • 编译期确定性:Pool的模板参数FooTypes...在编译期就确定了所有实例的类型和数量,std::tuple的大小也在编译期固定,无任何运行时动态分配。
  • 折叠表达式的应用:在execute_all()方法中,用折叠表达式(foo.Do(), ...)遍历tuple中的所有Foo实例,批量调用Do()方法,简洁高效。
  • 类型安全访问:通过get<Index>()方法可以在编译期指定索引获取对应Foo实例,保证类型安全,不会出现指针越界等运行时错误。

可行性结论

这个方案完全符合你的需求:

  • 全程无动态分配、无指针;
  • 所有实例的类型和数量在编译期确定;
  • 完美适配你定义的不可拷贝/移动的Foo类。

内容的提问来源于stack exchange,提问作者Guillaume BERLAND

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:05:15