简体   繁体   English

在工厂类中存储和传递参数包

[英]Storing and passing on parameter pack in factory class

I'm trying to write a "factory" class template whose instantiations have variadic constructors which store their arguments in a tuple and later pass on these arguments to the constructors of objects created by the factory.我正在尝试编写一个“工厂”类模板,其实例化具有可变参数构造函数,这些构造函数将它们的参数存储在一个元组中,然后将这些参数传递给工厂创建的对象的构造函数。

A minimal example might make it clearer:一个最小的例子可能会更清楚:

#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());

  // ...
}

My problem here is that the call to std::apply is apparently malformed since both gcc and clang complain along the lines of no matching function for call to '__invoke' .我的问题是,对std::apply的调用显然是格式错误的,因为 gcc 和 clang 都抱怨no matching function for call to '__invoke' What am I doing wrong here?我在这里做错了什么?

All you need to do is wrap the std::make_unique call into a perfect-forwarding lambda:您需要做的就是将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 Godbolt.org 上的现场示例

The reason is that std::make_unique doesn't only take a T template argument, but also Args... , which in this case are deduced by fowarding xs... .原因是std::make_unique不仅采用T模板参数,还采用Args... ,在这种情况下,它是通过转发xs...推导出来的。 Seecppreference .请参阅cppreference

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM