如何从模板方法中的参数包中移动 unique_ptr

How to move an unique_ptr from a parameter pack inside a template method

我想将参数包传递到模板方法中,该方法创建由另一个模板参数指定的类型的对象的新实例。

最小代码示例:

我的代码实际上对创建的类型和处理程序执行了更多操作

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

简单用法:

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

现在我的问题是我的论点之一是std::unique_ptr

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

编译失败,因为 std::unique_ptr 必须通过 CreateAndDo 方法移动。 我知道我需要继续移动参数,但我不知道如何使用参数包来做到这一点。

我怎样才能做到这一点?

嗯,为什么你搬args...

您总是在 CreateAndDo 中复制。没有理由这样做,而且它禁止您传递仅移动参数,正如您所发现的那样。

我看不出这与模板或参数包有任何关系,真的,除非问题是不清楚在那种情况下如何完成移动。问题不是如何将 unique_ptr 传递给参数包,而是之后如何处理它,这与没有参数包的情况一样——移动 unique_ptr

你也应该forward the args, which effectively does a move when appropriate and a copy otherwise. You'll need the argument to be a

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));
}

所以问题是你只移动在函数调用链的一部分,而不是第二部分,导致不必要的——有时是不可能的——复制。