将相同的参数转发给 C++ 中的可变参数元组构造函数

问题描述

TL;下面的DR

我正在尝试使用用于多核处理的包编写一些 C++ 代码。这个包有一个很好的发送者类,我用它在线程之间发送消息。它看起来像这样:

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

这个类的构造函数其实有点复杂,所以我希望构造函数只调用一次。 我不想为我需要的所有发件人使用容器类型,所以是这样的:

typedef std::tuple<
    sender<uint32_t,uint32_t>,sender<uint32_t,double>,double>
> sender_container_1_t;
typedef std::tuple<
    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,double> and sender<uint32_t,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,all constructed with a reference to gvc as an argument.
sender_container<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> my_container(gvc1),以便将gvc1 转发给所有发件人的构造函数。有人给个提示吗?

TL;博士: 如果我有一个可变参数结构模板

template<typename ...Ts>
struct Bar {
    Bar(Foo f){};
}

我可以制作一个表格的容器吗

template<typename ...Ts>
struct BarContainer{
    std::tuple<Bar<int,Ts>...> bars
}

这样我就可以调用 BarContainer<int,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;
}

Demo

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...