I'm having problems creating a push_back function for an std::vector of std::variants. This is a minimal implementation of my struct so far:
template<class T, class Ts...> //Must construct with at least 1 argument
struct entity_container
{
  entity_container(T arg1, Ts ...args) //constructor, populate vector of std::variant's
  {
    entities.push_back(std::forward<decltype(arg1)>(arg1));
    auto loop = [&](auto&& arg)
    {
      entities.push_back(std::forward<decltype(arg)>(arg));
    }
    (loop(args),...);
  }
  
  std::vector<std::variant<T, Ts...>> entities;
}
Now suppose I want to add a push_back function then there are some things I considered:
if we are adding a type which already exists in the
std::variantofentity_container::entitiesthen we can simply use:entities.push_back(entity)if we are adding a new type to
entity_container::entitiesthen we need to extended the type of thestd::variant, then create a newstd::vectorof said type and move all the elements from the old vector to the new one.
for this second case, I came across two posts:
extending a variant type in c++ and copy/move elements between two std::variants
So using these tools this is what I wanted to do for my push_back implementation:
template<typename E>
void push_back(E&& entity)
{
  if( /* E is a new type to the variant */)
  {
    //std::variant<Old..., New>  =  std::variant<Old...> + New
    using extended_type = t_variant_cat_t<std::remove_reference_t<decltype(Entities[0])>, 
                                          std::remove_reference_t<E>>;
    //construct (with the new element) a new entity_container with the extended type, 
    entity_container<extended_type> entities_new(entity);
    //move the entities from the old container to the new one
    for(auto& ent : Entities)
      entities_new.entities.push_back(std::move(ent));    //all entities are moveable types
    //update replace the old container with the new
    entities = entities_new;
  }
  else /* E is not a new type to the variant */
  {
    entities.push_back(entity);
  }
}
But there are many, many problems with this.
How can we check that the type
Eis a new type to the variant?extended_typewould be something along the lines ofstd::variant<T1, T2, T3, T4>but in reality we have to construct anentity_containerasentity_container<T1, T2, T3, T4>- how can we convert from anstd::variantto a type pack?when we do
entities = entities_newat the end, these two objects have different types and therefore cannot be assigned to one another (and that's even if (2) could be fixed)Finally, we have to reconstruct the container every single time an element is pushed back. That's gonna be really slow.
So my overall question is, does anyone have any ideas to fix the above problems, or perhaps a whole new approach to writing this function.
Side Note, the structure is used as so:
template<class T>
struct Entity{};
Entity<A> entity_a;
Entity<B> entity_b;
Entity<C> entity_c;
entity_container c(entity_a, entity_b);
c.push_back(entity_c);