【问题标题】:Creating containers for OpenSplice templates?为 OpenSplice 模板创建容器?
【发布时间】:2020-04-02 16:08:54
【问题描述】:

我正在尝试在 OpenSplice 中构建一个 C++ 程序,它允许用户指定应该加载的类型。通过使用 OpenSplice 的 IDL 预处理器 (IDLPP) 生成的 C++ 文件稍微复杂了一点,而不是共享一个通用接口或基类——而不是选择生成所有/大部分代码(我假设减少不必要的依赖)。

我为这个问题创建的解决方案是首先使用 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
}

从 cmets 中可以看出,这会根据我尝试修改的部分产生各种不同的错误。似乎最接近的方法是使用 TopicHolder(T, U) 构造函数,但是当我尝试实际读取元组时失败了

【问题讨论】:

    标签: c++ templates data-distribution-service opensplice


    【解决方案1】:

    您遇到了令人烦恼的解析问题

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

    使用TopicHolder&lt;chat::NameServiceType, chat::ChatMessageType&gt; topicHolder;TopicHolder&lt;chat::NameServiceType, chat::ChatMessageType&gt; 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_);
        // ...
    }
    

    【讨论】:

    • 哇。这太棒了,它完美地工作。在我工作的大部分时间里,这确实是一个问题,我非常感谢你解决它!
    猜你喜欢
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多