gpt4 book ai didi

c++ - 映射可变参数模板参数

转载 作者:太空宇宙 更新时间:2023-11-04 16:00:21 27 4
gpt4 key购买 nike

在下面的代码中,我想找到一种更通用的调用 GenericPublish__Advertise() 的方法,它采用可变参数模板列表。我可以做些什么来改进它?

我想将主题映射到特定类型的发布者:

  • 主题[0] -> 发布者[0]
  • 主题[1] -> 发布者[1]
  • 等等

虽然代码工作正常,但我需要手动编写 GenericPublish__Advertise() 的模板版本并手动将主题 [i] 映射到发布者。我想以某种方式概括 GenericPublish__Advertise() 的实现。

非常感谢。

代码:

    #include <iostream>
#include <memory>
#include <typeinfo>
#include <vector>

class AdvertiseOptionsBase {
public:
virtual const std::type_info &GetType() = 0;
};

template <typename TSend>
class AdvertiseOptions : public AdvertiseOptionsBase {
public:
AdvertiseOptions(TSend opt) : opt_(opt) {}
const std::type_info &GetType() { return typeid(opt_); }

private:
TSend opt_;
};

class Publisher {
public:
Publisher(const std::string &topic) : topic_(topic) {}
const std::string &GetTopic() const { return topic_; }
template <typename TSend>
void SetOptions(const AdvertiseOptions<TSend> &opt) {
options_ = std::make_unique<AdvertiseOptions<TSend>>(opt);
}
const std::unique_ptr<AdvertiseOptionsBase> &GetOptions() const {
return options_;
}

private:
std::string topic_;
std::unique_ptr<AdvertiseOptionsBase> options_;
};

class Node {
public:
template <typename TSend>
Publisher advertise(std::string topic) {
Publisher publisher(topic);
TSend option;
AdvertiseOptions<TSend> options(option);
publisher.SetOptions<TSend>(options);
return publisher;
}
};

template <typename TSend1, typename TSend2>
void GenericPublish__Advertise(Node &node, std::vector<Publisher> &publishers,
const std::vector<std::string> &topics) {
publishers.push_back(node.advertise<TSend1>(topics.at(0)));
publishers.push_back(node.advertise<TSend2>(topics.at(1)));
}
template <typename TSend1, typename TSend2, typename TSend3>
void GenericPublish__Advertise(Node &node, std::vector<Publisher> &publishers,
const std::vector<std::string> &topics) {
publishers.push_back(node.advertise<TSend1>(topics.at(0)));
publishers.push_back(node.advertise<TSend2>(topics.at(1)));
publishers.push_back(node.advertise<TSend3>(topics.at(2)));
}

template <typename... TSend>
class GenericPublish {
public:
GenericPublish(const std::vector<std::string> &topics) {
GenericPublish__Advertise<TSend...>(node_, publishers_, topics);
}
void PrintInfo() {
for (const auto &publisher : publishers_) {
std::cout << publisher.GetTopic() << " -----> "
<< (publisher.GetOptions()->GetType()).name() << std::endl;
}
}

protected:
Node node_;
std::vector<Publisher> publishers_;

private:
};

int main() {
std::vector<std::string> topics({"topic_int", "topic_double"});
GenericPublish<int, double> o(topics);
o.PrintInfo();
return 0;
}

最佳答案

这里的典型方法是使用 index sequence诡计。您采用类型的参数包,构建相同大小的索引序列,然后迭代两者:

template <typename... TSends> // <== pack of types
void GenericPublishAdvertise(Node &node, std::vector<Publisher> &publishers,
const std::vector<std::string> &topics)
{
GenericPublishAdvertiseImpl<TSends...>(node, publishers, topics,
std::index_sequence_for<TSends...>()); // <== index sequence creation
}

用单独的实现做:

template <typename... TSends, size_t... Is>
void GenericPublishAdvertiseImpl(Node &node, std::vector<Publisher> &publishers,
const std::vector<std::string> &topics, std::index_sequence<Is...> )
{
// since this is C++14
using swallow = int[];
(void)swallow{0,
(void(publishers.push_back(node.advertise<TSends>(topics.at(Is)))), 0)...
};

// in C++17, that's just
(publishers.push_back(node.advertise<TSends>(topics.at(Is))), ...);
}

参见 this answer用于解释该模式。


请注意,使用 GenericPublish__Advertise 是 UB:保留带有双下划线的名称。

关于c++ - 映射可变参数模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45841555/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com