用可变参数替换模板参数列表

问题描述 投票:0回答:1

有人可以帮助我如何用可变参数模板参数替换模板类型列表,并在类中创建每种类型的唯一指针。

问题是我有课

template <typename TA, typename TB1, typename TB2>
class Foo

我想扩展到 2 个以上

TB
类型

template <typename TA, typename ... TB>
class Foo

完整示例代码

#include <iostream>
#include <memory>

// Some concrete types
struct A
{
    A(int a) : a_(2*a){}
    void execute() const { std::cout << "A: " << a_ << "\n"; }
    int a_;
};
struct B1
{
    B1(int a, double b) : a_(a), b_(b){}
    void execute() const { std::cout << "B1: " << a_ << ", " << b_ << "\n"; }
    int a_; double b_;
};
struct B2
{
    B2(int a, double b) : a_(a*a), b_(b*b){}
    void execute() const { std::cout << "B2: " << a_ << ", " << b_ << "\n"; }
    int a_; double b_;
};

// Now declare a templated class
template <typename TA, typename TB1, typename TB2>
class Foo
{
private:
  // A unique pointer to each template type
  std::unique_ptr<TA>  m_a{};
  std::unique_ptr<TB1> m_b1{};
  std::unique_ptr<TB2> m_b2{};
public:
  Foo() = default;
  ~Foo() = default;
  
  void initialise(int a, double b)
  {
    m_a  = std::make_unique<TA>(a);
    m_b1 = std::make_unique<TB1>(a, b);
    m_b2 = std::make_unique<TB2>(a, b);
  }

  void execute() const
  {
    m_a->execute();
    m_b1->execute();
    m_b2->execute();
  }
};

int main(int, char**)
{
  // Use templated class
  Foo<A,B1,B2> foo;
  foo.initialise(5, 3.14159);
  foo.execute();
  return 0;
}

在类

Foo
中,我声明、实例化并使用指向每种类型
TB1
TB2
的唯一指针。只需 2 个模板参数,我就可以轻松做到这一点。但是,我不知道如何使用可变模板参数来做到这一点。

本质上我想改变

Foo
看起来像这样:

template <typename TA, typename ... TB>
class Foo
{
private:
  // A unique pointer to each template type
  std::unique_ptr<TA>  m_a{};
  // TODO: Declare list or tuple of unique pointers to each of the types in TB ...
public:
  Foo() = default;
  ~Foo() = default;
  
  void initialise(int a, double b)
  {
    m_a  = std::make_unique<TA>(a);
    // TODO: Instantiate the list/tuple of unique pointers
  }

  void execute() const
  {
    m_a->execute();
    // TODO: Call execute on the list/tuple of unique pointers
  }
};

我标记为 TODO 的部分是我不知道的部分(即使这完全可以完成)。

一些注意事项

  • TB
    类是不同的,不一定有共同的基类
  • TB
    类没有默认构造函数。
  • 我们可以假设
    TB
    类具有具有相同签名的非默认构造函数。

当然,我也愿意采用完全不同的方法,它允许我拥有多达 6 TB 的类,而无需太多代码重复。

c++ c++14 variadic-templates
1个回答
0
投票

也许是这样的(未经测试):

template <typename TA, typename ... TB>
class Foo
{
private:
  std::unique_ptr<TA>  m_a{};
  std::tuple<std::unique_ptr<TB>...> m_bs;

public:
  void initialise(int a, double b)
  {
    m_a  = std::make_unique<TA>(a);
    std::apply([&](std::unique_ptr<TB>&... p) {
        (void(p = std::make_unique<TB>(a, b)), ...);
      },
      m_bs);
  }

  void execute() const
  {
    m_a->execute();
    std::apply([&](std::unique_ptr<TB>&... p) {
        (void(p->execute()), ...);
      },
      m_bs);
  }
};
© www.soinside.com 2019 - 2024. All rights reserved.