0

I want to pass a parameter pack into a template method that creates a new instance of an object of a type specified by another template argument.

Minimal code example:

my code actually does more operations with the created type and the handler

template<typename T, typename... Args>
static bool CreateAndDo(Handler & rHandler, Args.. args)
{
  auto pT = T::Create(args...);
  rHandler.DoStuff(std::move(pT));
}

Simple Usage:

Handler tHander;
// the 0 is just an example of an argument
CreateAndDo<ConcreteType>(tHander, 0);

Now my problem is that one of my arguments is a std::unique_ptr.

auto pPtr = std::make_unique<ConcreteArg>();
CreateAndDo<ConcreteType>(tHander, std::move(pPtr));

This fails to compile, because the std::unique_ptr would have to be moved by CreateAndDo Method. I know that I need to keep moving the arguments but I don't know how to do that with a parameter pack.

How could I accomplish this?

The Shmoo
  • 196
  • 12

1 Answers1

5

Well, why don't you move args...?

You're always copying, inside CreateAndDo. There's no reason to, and it forbids you from passing move-only args, as you've found.

I can't see that this has anything to do with templates or parameter packs, really, unless the issue is that it was unclear how to accomplish a move in that situation. The question isn't how to pass a unique_ptr to a parameter pack, but what to do with it afterwards, and that is just the same as you would without a parameter pack — move a unique_ptr around.

You should forward the args, which effectively does a move when appropriate and a copy otherwise. You'll need the argument to be a forwarding reference, too.

template<typename T, typename... Args>
static bool CreateAndDo(Handler & rHandler, Args&&.. args)
{
  auto pT = T::Create(std::forward<Args>(args)...);
  rHandler.DoStuff(std::move(pT));
}

So the problem is that you only moved at one part of the chain of function calls, but not the second part, resulting in an unnecessary — and sometimes impossible — copy.

Lightness Races in Orbit
  • 358,771
  • 68
  • 593
  • 989