In a previous post, I've asked about how one can map variadic template arguments to a vector of inputs.
I have the following extended code, in which I'm trying to use two variadic templates (TSends, TReceives). They are supposed to specify a variadic list of types for a publisher and another variadic list of types for a subscriber.
I cannot seem to get it running (cannot compile). Can anyone please help?
Many thanks in advance!
#include <iostream>
#include <memory>
#include <typeinfo>
#include <vector>
class AdvertiseOptionsBase {
public:
virtual const std::type_info &GetType() = 0;
};
template <typename TSends>
class AdvertiseOptions : public AdvertiseOptionsBase {
public:
AdvertiseOptions(TSends opt) : opt_(opt) {}
const std::type_info &GetType() { return typeid(opt_); }
private:
TSends opt_;
};
class Publisher {
public:
Publisher(const std::string &topic) : topic_(topic) {}
const std::string &GetTopic() const { return topic_; }
template <typename TSends>
void SetOptions(const AdvertiseOptions<TSends> &opt) {
options_ = std::make_unique<AdvertiseOptions<TSends>>(opt);
}
const std::unique_ptr<AdvertiseOptionsBase> &GetOptions() const {
return options_;
}
private:
std::string topic_;
std::unique_ptr<AdvertiseOptionsBase> options_;
};
class Subscriber {
public:
Subscriber(const std::string &topic) : topic_(topic) {}
const std::string &GetTopic() const { return topic_; }
template <typename TSends>
void SetOptions(const AdvertiseOptions<TSends> &opt) {
options_ = std::make_unique<AdvertiseOptions<TSends>>(opt);
}
const std::unique_ptr<AdvertiseOptionsBase> &GetOptions() const {
return options_;
}
private:
std::string topic_;
std::unique_ptr<AdvertiseOptionsBase> options_;
};
class Node {
public:
template <typename TSends>
Publisher advertise(std::string topic) {
Publisher publisher(topic);
TSends option;
AdvertiseOptions<TSends> options(option);
publisher.SetOptions<TSends>(options);
return publisher;
}
template <typename TReceive>
Subscriber subscribe(std::string topic){
Subscriber subscriber(topic);
TReceive option;
AdvertiseOptions<TReceive> options(option);
subscriber.SetOptions<TReceive>(options);
return subscriber;
}
};
template <typename... TSends, size_t... Is>
void GenericPublishSubscribe_AdvertiseImpl(Node &node, std::vector<Publisher> &publishers,
const std::vector<std::string> &topics, std::index_sequence<Is...> )
{
using swallow = int[];
(void)swallow{0,
(void(publishers.push_back(node.advertise<TSends>(topics.at(Is)))), 0)...
};
}
template <typename... TSends>
void GenericPublishSubscribe_Advertise(Node &node, std::vector<Publisher> &publishers,
const std::vector<std::string> &topics)
{
GenericPublishSubscribe_AdvertiseImpl<TSends...>(node, publishers, topics,
std::index_sequence_for<TSends...>());
}
template <typename... TReceives, size_t... Is>
void GenericPublishSubscribeSubscribeImpl(Node &node, std::vector<Publisher> &subscribers,
const std::vector<std::string> &topics, std::index_sequence<Is...> )
{
using swallow = int[];
(void)swallow{0,
(void(subscribers.push_back(node.subscribe<TReceives>(topics.at(Is)))), 0)...
};
}
template <typename... TReceives>
void GenericPublishSubscribeSubscribe(Node &node, std::vector<Subscriber> &subscribers,
const std::vector<std::string> &topics)
{
GenericPublishSubscribeSubscribeImpl<TSends...>(node, subscribers, topics,
std::index_sequence_for<TSends...>());
}
template < template <typename... TSends> typename TS,
template <typename... TReceives> typename TR>
class GenericPublishSubscribe {
public:
GenericPublishSubscribe(const std::vector<std::string> &publisher_topics, const std::vector<std::string> &subscriber_topics) {
GenericPublishSubscribe_Advertise <TSends...>(node_, publishers_, publisher_topics);
GenericPublishSubscribe_Subscribe <TReceives...>(node_, subscribers_, subscriber_topics);
}
void PrintInfo() {
std::cout<<"Publishers:"<<std::endl<<std::endl;
for (const auto &publisher : publishers_) {
std::cout << publisher.GetTopic()
<< " --> "
<< (publisher.GetOptions()->GetType()).name()
<< std::endl;
}
std::cout<<std::endl<<"Subscribers:"<<std::endl<<std::endl;
for (const auto &subscriber : subscribers_) {
std::cout << subscriber.GetTopic()
<< " --> "
<< (subscriber.GetOptions()->GetType()).name()
<< std::endl;
}
}
protected:
Node node_;
std::vector<Publisher> publishers_;
std::vector<Subscriber> subscribers_;
private:
};
int main() {
std::vector<std::string> publisher_topics({"topic_int", "topic_double"});
std::vector<std::string> subscriber_topics({"topic_char", "topic_byte"});
GenericPublishSubscribe<<int, double>,<char, byte>> o(publisher_topics, subscriber_topics);
o.PrintInfo();
return 0;
}
Aucun commentaire:
Enregistrer un commentaire