有人可以帮助我如何用可变参数模板参数替换模板类型列表,并在类中创建每种类型的唯一指针。
问题是我有课
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 的类,而无需太多代码重复。
也许是这样的(未经测试):
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);
}
};