【问题标题】:Storing and passing on parameter pack in factory class在工厂类中存储和传递参数包
【发布时间】:2020-10-08 15:54:51
【问题描述】:

我正在尝试编写一个“工厂”类模板,其实例化具有可变参数构造函数,这些构造函数将它们的参数存储在一个元组中,然后将这些参数传递给工厂创建的对象的构造函数。

一个最小的例子可能会更清楚:

#include <memory>
#include <tuple>

struct Foo
{
  Foo(int arg1, double arg2)
  {}

  // ...
};

template<typename T, typename ...ARGS>
class Factory
{
public:
  Factory(ARGS&&... args)
  : _stored_args(std::make_tuple(std::forward<ARGS>(args)...))
  {}

  std::unique_ptr<T> create()
  { return std::apply(std::make_unique<T>, _stored_args); }

private:
  std::tuple<ARGS...> _stored_args;
};

template<typename T, typename ...ARGS>
std::unique_ptr<Factory<T, ARGS...>> make_factory(ARGS&&... args)
{ return std::make_unique<Factory<T, ARGS...>>(std::forward<ARGS>(args)...); }

int main()
{
  auto foo_factory(make_factory<Foo>(1, 2.0));

  auto foo_ptr(foo_factory->create());

  // ...
}

我的问题是对std::apply 的调用显然格式不正确,因为gcc 和clang 都按照no matching function for call to '__invoke' 的方式抱怨。我在这里做错了什么?

【问题讨论】:

  • 你能解释一下create应该做什么吗?
  • @cigien 将unique_ptr 返回到T 类型的对象。我还没有解释我使用这个工厂类的目的是什么,但我认为没有必要理解这个问题。
  • 不,我的意思是,是什么让你认为你需要apply?从tuple&lt;Args...&gt; 生成unique_ptr&lt;T&gt; 的逻辑是什么?

标签: c++ templates c++17 variadic-templates


【解决方案1】:

您需要做的就是将 std::make_unique 调用包装成一个完美转发的 lambda:

std::unique_ptr<T> create() {
return std::apply(
    [](auto&&... xs) {
        return std::make_unique<T>(std::forward<decltype(xs)>(xs)...);
    },
    _stored_args);
}

live example on godbolt.org

原因是std::make_unique 不仅接受T 模板参数,还接受Args...,在这种情况下通过转发xs... 推导出。见cppreference

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 2014-11-08
    • 2016-09-12
    • 1970-01-01
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多