【问题标题】:Store template parameter pack as a attribute of a non class template将模板参数包存储为非类模板的属性
【发布时间】:2019-08-07 21:49:04
【问题描述】:

是否可以将传递给非类模板的构造函数的可变参数模板参数/参数包存储为该类的属性而不将该类转换为类模板?

我目前正在开发一个瘦包装类(我在这里只创建了一个最小的示例以最大程度地降低复杂性),它具有以下签名:

class Wrapper final {
 public:
  template <typename Function, typename... Args>
  auto start(Function&& function, Args&&... args) -> void;
};

参数包被传递给成员函数模板start&lt;Function, ... Args&gt;,目前不需要“存储”functionargs。完美转发用于该功能内的进一步处理。

现在,我想要实现的签名如下(引入一个接口类):

class WrapperInterface {
 public:
  virtual ~WrapperInterface() = default;

  virtual auto start() -> void = 0;
};

// TODO(2019-03-17 by wolters) The following is non-working pseudo-code.
class Wrapper final : public WrapperInterface {
 public:
  template <typename Function, typename... Args>
  explicit Wrapper(Function&& function, Args&&... args)
      : function_{function}, args_{args} {
    // NOOP
  }

  auto start() -> void {
    // TODO(2019-03-17 by wolters) Invoke `function_` with `args_`.
    function_(args);
  }

 private:
  std::function<???> function_;
  std::tuple<???> args_;
};

那么Wrapper可以这样使用:

class WrapperClient final {
 public:
  WrapperClient() : wrapper_{[this](){
    // std::cout << "started\n";
  }} {
    // NOOP
  }

 private:
  Wrapper wrapper_;
};

虽然接口类在上面的例子中不是必需的,但一般来说它是必需的,因为实例应该存储在std::vector&lt;std::unique_ptr&lt;WrapperInterface&gt;&gt;中。

我已经阅读并尝试过How to store variadic template arguments?,但这种方法需要将Wrapper 转换为类模板。

我认为需要与QThread *QThread::create(Function &amp;&amp;f, Args &amp;&amp;... args) implementation 类似的东西。遗憾的是,该代码对我来说太高级了。

你能引导我走向正确的方向吗?是否可以使用私有实现类模板?

【问题讨论】:

  • 您不能使用std::function&lt;void()&gt; 并在其中存储[=]{function(args...);} 吗?

标签: c++ c++11 templates parameter-passing variadic-templates


【解决方案1】:

您正在尝试做的事情称为类型擦除,这是一种非常有趣的技术(示例和无耻的自我推销here),但它已经在std::function 中为您完成,所以您要做的就是是使用 std::function&lt;void()&gt; 并使用 std::bind 或 lambda 捕获来存储参数:

template <typename Function, typename... Args>
std::function<void()> wrap(Function&& function, Args&&... args)
{
    return [=] { function(args); };
    // or return std::bind(std::forward<Function>(function), std::forward<Args>(args)...);
}

【讨论】:

  • 你让我走上了正轨。使用std::function 是解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 2019-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多