将相同的参数转发给 C++ 中的可变元组构造函数
Forward the same argument to variadic tuple constructor in C++
TL;低于 DR
我正在尝试使用用于多核处理的包编写一些 C++ 代码。该包有一个很好的发件人 class,我用它在线程之间发送消息。它看起来像这样:
// structs provided by the package
struct GlobalVarsContainer {
// some global vars
};
template<typename ...Ts>
struct sender {
GlobalVarsContainer* my_container;
sender (GlobalVarsContainer& c) : my_container(&c);
void send(Ts... args) {
// send the messages of types Ts
};
};
这个class的构造函数实际上有点复杂,所以我希望只调用一次构造函数。
我想为我需要的所有发件人使用容器类型,所以像这样:
typedef std::tuple<
sender<uint32_t,uint32_t>,
sender<uint32_t,double>,
sender<uint32_t,double>
> sender_container_1_t;
typedef std::tuple<
sender<uint32_t,double>,
sender<uint32_t,double>,
sender<uint32_t,double>
> sender_container_2_t;
现在我可以构造一个 sender_container_1_t
并通过引用传递给我的所有函数,欢呼!
但这很难看,你必须像这样实例化容器:
GlobalVarsContainer gvc1, gvc2;
sender_container_1_t c1(gvc1, gvc1, gvc1);
sender_container_2_t c2(gvc2, gvc2, gvc2);
我想要一些形式
GlobalVarsContainer gvc1, gvc2;
// Should have a tuple of senders of type sender<uint32_t,uint32_t>, sender<uint32_t,double> and sender<uint32_t,double>, all constructed with a reference to gvc as an argument.
sender_container<uint32_t,double,double> c1(gvc1);
// Should have a tuple of senders of type sender<uint32_t,double>, sender<uint32_t, double> and sender<uint32_t, double>, all constructed with a reference to gvc as an argument.
sender_container<double,double,double> c2(gvc2);
所以我想到了使用可变容器结构,像这样:
// My sender container
template<typename... Ts>
struct SenderContainer {
std::tuple<sender<uint32_t, Ts>...> my_senders;
// What to do for the constructor ?
};
但我不知道该怎么做才能 SenderContainer<uint32_t,double,double> my_container(gvc1)
将 gvc1
转发给所有发件人的构造函数。有人有提示吗?
长话短说:
如果我有可变结构模板
template<typename ...Ts>
struct Bar {
Bar(Foo f){};
}
我可以做一个这样的容器吗
template<typename ...Ts>
struct BarContainer{
std::tuple<Bar<int,Ts>...> bars
}
这样我就可以调用 BarContainer<int, double, long> newBarContainer(f)
并将 Foo f
转发给 BarContainer::bars
的所有构造函数。
您可以创建虚拟结构以允许您的 pack expansion:
template <typename> struct tag{};
template<typename ...Ts>
struct Bar {
Bar(Foo f){};
};
template<typename ...Ts>
struct BarContainer{
BarContainer(Foo f) : bars{(tag<Ts>{}, f)...} {}
std::tuple<Bar<int,Ts>...> bars;
}
TL;低于 DR
我正在尝试使用用于多核处理的包编写一些 C++ 代码。该包有一个很好的发件人 class,我用它在线程之间发送消息。它看起来像这样:
// structs provided by the package
struct GlobalVarsContainer {
// some global vars
};
template<typename ...Ts>
struct sender {
GlobalVarsContainer* my_container;
sender (GlobalVarsContainer& c) : my_container(&c);
void send(Ts... args) {
// send the messages of types Ts
};
};
这个class的构造函数实际上有点复杂,所以我希望只调用一次构造函数。 我想为我需要的所有发件人使用容器类型,所以像这样:
typedef std::tuple<
sender<uint32_t,uint32_t>,
sender<uint32_t,double>,
sender<uint32_t,double>
> sender_container_1_t;
typedef std::tuple<
sender<uint32_t,double>,
sender<uint32_t,double>,
sender<uint32_t,double>
> sender_container_2_t;
现在我可以构造一个 sender_container_1_t
并通过引用传递给我的所有函数,欢呼!
但这很难看,你必须像这样实例化容器:
GlobalVarsContainer gvc1, gvc2;
sender_container_1_t c1(gvc1, gvc1, gvc1);
sender_container_2_t c2(gvc2, gvc2, gvc2);
我想要一些形式
GlobalVarsContainer gvc1, gvc2;
// Should have a tuple of senders of type sender<uint32_t,uint32_t>, sender<uint32_t,double> and sender<uint32_t,double>, all constructed with a reference to gvc as an argument.
sender_container<uint32_t,double,double> c1(gvc1);
// Should have a tuple of senders of type sender<uint32_t,double>, sender<uint32_t, double> and sender<uint32_t, double>, all constructed with a reference to gvc as an argument.
sender_container<double,double,double> c2(gvc2);
所以我想到了使用可变容器结构,像这样:
// My sender container
template<typename... Ts>
struct SenderContainer {
std::tuple<sender<uint32_t, Ts>...> my_senders;
// What to do for the constructor ?
};
但我不知道该怎么做才能 SenderContainer<uint32_t,double,double> my_container(gvc1)
将 gvc1
转发给所有发件人的构造函数。有人有提示吗?
长话短说: 如果我有可变结构模板
template<typename ...Ts>
struct Bar {
Bar(Foo f){};
}
我可以做一个这样的容器吗
template<typename ...Ts>
struct BarContainer{
std::tuple<Bar<int,Ts>...> bars
}
这样我就可以调用 BarContainer<int, double, long> newBarContainer(f)
并将 Foo f
转发给 BarContainer::bars
的所有构造函数。
您可以创建虚拟结构以允许您的 pack expansion:
template <typename> struct tag{};
template<typename ...Ts>
struct Bar {
Bar(Foo f){};
};
template<typename ...Ts>
struct BarContainer{
BarContainer(Foo f) : bars{(tag<Ts>{}, f)...} {}
std::tuple<Bar<int,Ts>...> bars;
}