可变模板继承,成员函数重载

adr*_*ino 2 c++ templates variadic-templates c++11 ros

我正在尝试使用可变参数模板重写模板类http://docs.ros.org/hydro/api/rviz/html/c++/message__filter__display_8h_source.html以用于多种消息类型。

我的第一个问题是如何使用可变参数模板重写下面的示例代码,以便它可以与任意数量的模板参数一起使用,而不仅仅是 2。

我在父类中需要什么:

  • processMessage每个模板化类型的虚拟成员函数
  • incomingMessage每个模板类型的每个成员函数
  • 每个模板化类型的成员变量。(稍后将成为 ROS 中该 MessageType 主题的订阅者)

因此,如果例如使用 2 个模板类型调用,则可变参数基类应编译为如下所示:

包括:

#include<string>
#include<sstream>
#include<iostream>
using namespace std;
Run Code Online (Sandbox Code Playgroud)

工作代码(通常的模板):

template<class MessageType1,class MessageType2> class Parent{
public:

    Parent() : messages_received_(0){}

    virtual void processMessage(MessageType1 msg) = 0;
    virtual void processMessage(MessageType2 msg) = 0;

    void incomingMessage(MessageType1 msg){
        processMessage(msg);
        incr();
    }

    void incomingMessage(MessageType2 msg){
        processMessage(msg);
        incr();
    }

private:
    void incr(){
        cout<<"received "<<++messages_received_<<endl;;
    }

    MessageType1 sub1_;
    MessageType2 sub2_;

    int messages_received_;
};
Run Code Online (Sandbox Code Playgroud)

不工作(可变参数):

template<class... Elements> class Parent;
template<> class Parent<>{};

template<class Head, class... Tail> class Parent<Head, Tail...> : public Parent<Tail...> {
public:
    Parent() : messages_received_(0){}

    virtual void processMessage(Head msg) = 0;

    void incomingMessage(Head msg){
        processMessage(msg);
        incr();
    }

private:
    void incr(){
        cout<<"received "<<++messages_received_<<endl;;
    }

    Head sub1_;

    int messages_received_;
};
Run Code Online (Sandbox Code Playgroud)

编译失败:

#include<string>
#include<sstream>
#include<iostream>
using namespace std;
Run Code Online (Sandbox Code Playgroud)

所以我想不知何故,成员函数processMessage只编译为processMessage(std::string s)而不是重载版本processMessage(int a)

用法示例:

class Child : public Parent<std::string, int> {
public:
    void processMessage(std::string msg){
        cout<<"string: "<<msg<<endl;
    }

    void processMessage(int msg){
        cout<<"int: "<<msg<<endl;
    }
};

int main()
{
        Child myMfd;

        myMfd.incomingMessage(42);
        myMfd.incomingMessage("abc");

        return 0;
}
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?

Sam*_*hik 5

我还没有测试过这个,但它应该是这样的:

template<typename ...Args> class Parent;

template<> class Parent<> {

public:
    void incr();
    void incomingMessage() {}
};

template<typename MessageType, typename ...Args>
class Parent<MessageType, Args...> : public Parent<Args...> {

public:
    virtual void processMessage(MessageType msg)=0;

    using Parent<Args...>::incomingMessage;
    void incomingMessage(MessageType msg)
    {
        processMessage(msg);
        this->incr();
    }
};
Run Code Online (Sandbox Code Playgroud)

这并不完美,您需要从前一个类“传播”incomingMessage,以便它在“顶级范围”中正确解析,因此需要根超类中的难看的incomingMessage()。多做一点工作,也可能有办法解决这个问题。