Создание контейнеров для шаблонов OpenSplice? - PullRequest
0 голосов
/ 02 апреля 2020

Я пытаюсь построить программу на C ++ в OpenSplice, которая позволяет пользователю указывать типы, которые должны быть загружены. Это немного усложняется файлами C ++, сгенерированными с использованием препроцессора IDL (IDLPP) OpenSplice, а не использование общего интерфейса или базового класса - вместо этого я решил сгенерировать весь / большую часть кода (я предполагаю сократить ненужные зависимости).

Решение, которое я создал для этой проблемы, состоит в том, чтобы сначала сгенерировать заголовок файл со скриптом python, который затем вызывается основной программой. Это позволило бы сгенерировать все операторы включения и добавить типы, созданные IDLPP, как определено. Проблема с этим тогда ссылается на эти определения позже. Я хотел бы решить эту проблему, сохраняя определенные объекты в контейнере, а затем просто ссылаясь на них по номеру.

Проблема в том, что, поскольку они не имеют общего базового класса, C ++ не обеспечить простой способ хранить их в одном контейнере. Для справки, объекты OpenSplice обычно создаются примерно так (полу-аналог кортежей или векторов в STL):

dds::topic::Topic<moduleName::classType> variableName(params);

Я хотел бы хранить эти различные типы объектов в одном контейнере. Повторяющийся и «уродливый» код не является большой проблемой, так как я все равно создаю эти файлы. Это моя текущая попытка реализации:

#include <tuple>

template<class T, class U>
class TopicHolder{
public:
    std::tuple<dds::topic::Topic<T>, dds::topic::Topic<U>> tuple_;

    //empty constructor (error: no matching function for call to 'std::tuple<dds::topic::Topic<chat::NameServiceType, dds::topic::detail::Topic>,
    //  dds::topic::Topic<chat::ChatMessageType, dds::topic::detail::Topic>>::tuple()')
    TopicHolder(){}

    //or leave out the default constructor altogether (error: use of deleted function + note: implicity deleted because the default definition would be ill formed)
    //also previous error   

    //put the template in the constructor? (see main below for issues)
    TopicHolder(T, U){
        dds::domain::DomainParticipant dp(0);
        dds::topic::Topic<T> top1(dp, "top1");
        dds::topic::Topic<U> top2(dp, "top2");
        tuple_ = std::make_tuple(top1, top2);
    }

    void storeTopics(std::tuple<dds::topic::Topic<T>, dds::topic::Topic<U>> topics){
        tuple_ = topics;
    }
};

int main(){
    //call templated constructor?
    TopicHolder<chat::NameServiceType, chat::ChatMessageType> topicHolder();
    //all good, now try to pull tuple out...
    auto outTopic = std::get<0>(topicHolder.tuple_);
    //error: request for member 'tuple_' in 'topicHolder', which is of non-class type 'TopicHolder<chat::NameServiceType, chat::ChatMessageType>()'
    //leave out brackets in TopicHolder constructor: error: no matching function for call to 'TopicHolder<chat::NameServiceType, chat::ChatMessageType>::Topic()'

    return 0
}

Как видно из комментариев, это создает множество различных ошибок в зависимости от частей, которые я пытался изменить. Кажется, что наиболее близким подходом является использование конструктора TopicHolder(T, U), но это не удается, когда я пытаюсь действительно прочитать кортеж

1 Ответ

1 голос
/ 02 апреля 2020

У вас досадная проблема с синтаксическим анализом

// Function declaration
TopicHolder<chat::NameServiceType, chat::ChatMessageType> topicHolder();

Либо используйте TopicHolder<chat::NameServiceType, chat::ChatMessageType> topicHolder;, либо TopicHolder<chat::NameServiceType, chat::ChatMessageType> topicHolder{};

Тогда ваш член не может быть доступен по умолчанию, поэтому вы должны использовать список инициализатора ( что в любом случае хорошо).

Вы можете так сделать:

template<class T, class U>
class TopicHolder{
public:
    dds::domain::DomainParticipant dp_{0};
    std::tuple<dds::topic::Topic<T>, dds::topic::Topic<U>> tuple_;

    TopicHolder() : tuple_{dds::topic::Topic<T>(dp, "top1"), dds::topic::Topic<U>(dp, "top2")} {
    }

    void storeTopics(std::tuple<dds::topic::Topic<T>, dds::topic::Topic<U>> topics){
        tuple_ = topics;
    }
};

int main(){
    TopicHolder<chat::NameServiceType, chat::ChatMessageType> topicHolder;

    auto& outTopic = std::get<0>(topicHolder.tuple_);
    // ...
}
...