提问人:messenjah 提问时间:10/22/2023 更新时间:10/22/2023 访问量:62
将模板参数列表替换为可变参数
Replace template parameter list with variadic parameter
问:
有人可以帮助我如何用可变参数模板参数替换模板类型列表,并在类中为每个类型创建唯一指针。
问题是我有一个班级
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;
}
在我声明的类中,实例化并使用指向每个类型和 .只需 2 个模板参数,我就可以轻松做到这一点。但是,我不知道如何使用可变参数模板参数执行此操作。Foo
TB1
TB2
从本质上讲,我想改成这样的样子: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 的类,而无需太多代码重复。
答:
2赞
Igor Tandetnik
10/22/2023
#1
也许(未经测试):
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);
}
};
评论
0赞
messenjah
10/23/2023
谢谢。这很完美。只需要添加到第二个 lambda 中的参数包中,因为 中的方法 是 .const
execute
Foo
const
评论