1

I'd like to create template function that would create object basing on template typename and parameters pack.

I created a function that is supposed to create object based on typename from template, and I would also like to pass parameters pack to that template i order to pass parameters to constructor. Is this correct?:

template<typename TComponent, typename... Args>
    void CreateComponent(Args... args) 
    {
        std::shared_ptr<TComponent> component = std::make_shared<TComponent>(args ...);
    }

I also wanted to pass those parameters to another fucntion like this:

template<typename TComponent, typename... Args>
    void AddComponent(Args... args) 
    {
          m_world->AddComponent<TComponent, Args>(m_id, args...);
    }

But compiler returns an error " 'args' parameter pack must be expanded in this context"

Is it even possible to achieve what I want to achieve ?

max66
  • 65,235
  • 10
  • 71
  • 111
  • 1
    With perfect forwarding: `template void CreateComponent(Args&&... args) { auto component = std::make_shared(std::forward(args)...);}` – Jarod42 May 22 '19 at 19:47

1 Answers1

4

But compiler returns an error " 'args' parameter pack must be expanded in this context"

Yes: you've forgotten to expand the types

m_world->AddComponent<TComponent, Args...>(m_id, args...);
// ...................................^^^

As pointed by Jarod42, according to the circumstances, you could avoid to explicit the Args... expansion

m_world->AddComponent<TComponent>(m_id, args...);
// no more Args...

and let the compiler deduce the types through args... (but we should see the AddComponent() definition).

Anyway, I don't see errors in your CreateComponents() function but, as correctly says François Andrieux in a comment, you don't using perfect forwarding.

It's a too-great argument to explain in an answer but, this way, you're renouncing to move semantics advantages (that is: you, potentially, make some unnecessary copies).

The following is your CreateComponents() function enabling perfect forwarding

template <typename TComponent, typename ... Args>
void CreateComponent (Args && ... args) 
 { // .....................^^ forwarding reference added
   std::shared_ptr<TComponent> component
     = std::make_shared<TComponent>(std::forward<Args>(args)...);
 } // ..............................^^^^^^^^^^^^^^^^^^^^^^^^
max66
  • 65,235
  • 10
  • 71
  • 111