1

I'm learning about Variadic Template and Fold Expression. I would like to avoid the use of dynamic allocation and pointers.

To illustrate my problem, I created the Foo (copy and move constructors are deleted) class which inherits from I_Foo.

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

template <int a, int b>
class Foo : public I_Foo
{
public:
    explicit Foo(int x) : m_x {x} {}
    Foo(const Foo &) = delete;
    virtual ~Foo() {}
    Foo & operator=(const Foo &) = delete;
protected:
    virtual void Do() override { /* Do something */}
private:
    static constexpr std::size_t k_ArraySize {a * b};
    std::array<int, k_ArraySize> m_Array {};
    int m_x;
};

I would like to create a Pool class containing x I_Foo set at compile time but I have no idea how to do that. I'm completely lost. Instantiating the Pool could look like this:

template<typename... Args>
class Pool
{
public:
    explicit Pool(Args&&... args) : /* No idea */ {}
private:
    Foo1
    Foo2
    ...
    FooX
};

Pool<Foo<1,2>, Foo<3,2>> l_t_Pool { Foo<1,2>{1}, Foo<3,2>{2} };

My lack of knowledge does not allow me to know if this is possible. :(

  • `Add members at compile time` this isn't possible. It requires dynamic dispatching and reflection to be available – phuclv Jan 15 '23 at 11:58
  • I don't understand what you are trying to do. Forget "at compile-time" and "variadic" for a moment. If you had just one `I_Foo1` in `Pool` and you would be fine with working at runtime, what would you expect your constructor of `Pool` to do? `I_Foo1` is abstract, so you can't have a member of that type in the class. Even if you replace it with `I_Foo1*` instead, where do you expect the actual `Foo` object to be stored if not using dynamic allocation? Why can't `Pool` store a `Foo` directly if its value and type is decided at compile-time anyway? – user17732522 Jan 15 '23 at 12:12
  • 1
    With tuple we can store all Foo? – Guillaume BERLAND Jan 15 '23 at 13:06
  • You’ll need to store them in a std::vector (other collections are available) since you can’t change a class structure at run time. – QuentinUK Jan 15 '23 at 13:23
  • @GuillaumeBERLAND Note `tuple` doesn't necessarily store any data as a class member directly, hence you don't have easy access to the data with something like `my_tuple._0` and `my_tuple._N`, and need to call `get<0>(my_tuple)` and `get(my_tuple)` instead. – Ranoiaetep Jan 15 '23 at 13:25
  • `Pool, Foo<3,2>> l_t_Pool { Foo<1,2>{1}, Foo<3,2>{2} };` syntax can't work because it would require copying `Foo` instances, but you specifically want them non-copyable. If you know that each `Foo`'s constructor takes one int as a parameter, then `Pool, Foo<3,2>> l_t_Pool { 1, 2 };` can be made to work. – Igor Tandetnik Jan 15 '23 at 15:15
  • @Igor Tandetnik All Foo 's constructor are the same. – Guillaume BERLAND Jan 15 '23 at 15:20
  • 2
    Then [something like this](https://godbolt.org/z/P88x8fsGW). I removed the base class as that's irrelevant to the example. – Igor Tandetnik Jan 15 '23 at 15:28

0 Answers0