c++ - 将模板参数包存储为非类模板的属性

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

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

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

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

参数包传递给成员函数模板start<Function, ... Args>而且目前也不需要“存储” functionargs .完美转发用于该函数内的进一步处理。

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

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

虽然在上面的示例中不需要接口(interface)类,但通常需要它,因为实例应该存储在std::vector<std::unique_ptr<WrapperInterface>> 中。 .

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

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

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

最佳答案

你正在尝试做的是所谓的类型删除,这是一种非常有趣的技术(示例和无耻的 self 推销 here ),但它已经在 std::function 中为你完成了。 , 所以你所要做的就是使用 std::function<void()>并使用 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)...);
}

关于c++ - 将模板参数包存储为非类模板的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55205909/

相关文章:

c++ - 为命名空间中的类模板重载输出运算符

c++ - 在类中重载运算符[],因此它可以从模板类中的数组返回对象

c++ - 使用 boost 文件系统解析符号链接(symbolic link)

c++ - 设计一个只能由特定类实例化的类(如果可能,通过 make_unique)

c++ - g++ 可变参数模板。简单示例代码无法编译,提示 'Not a template'

C++11构造函数和析构函数顺序

c++ - 使用模板和继承的容器实现

c++ - 我如何更改显示在 QPushButton 上的数字?

c++ - 如何在 C++ 中逐个元素地比较两个 vector 的相等性?

C++ 使用 WinINet 上传到 FTP 服务器