1

我已经定义了一个“顶点”类,当它组合在一起时,就形成了一个图形。这些顶点在一端接收输入并在另一端产生输出(这两个端都可以有此顶点类的其他实例的 0、1 或多个“订阅”)传入和传出数据的类型都独立于每个其他 和 被指定为模板参数,因为这些顶点必须对各种输入/输出类型进行操作。

所以在代码中变成:

template<class incomingDataType, class OutgoingDataType>
    class Vertex {...}

在发送接收到的数据之前,顶点可以应用过滤器函数来转换/过滤数据,然后再将其再次发送回其列表订阅者。该函数被声明为纯虚函数,因为它的功能取决于从该虚拟顶点基类继承的特化类的种类。

这意味着过滤器被声明为:

OutgoingDataType filter(incomingDataType data) = 0; 

当然,我想将多个顶点相互链接在一起。以最简单的形式考虑这种链接,其中每个顶点的输入和输出都连接到另一个顶点的输入/输出:

(ClassX)vertex1(int) --> (int)vertex2(std::string) --> (std::string)vertex3(OtherClassOrType) -->...

考虑到这一点,给定示例的问题陈述如下
vertex2 必须将 vertex1 列为订阅者并将其自身订阅到 vertex3。为了跟踪所有这些订阅,顶点保存一组指向其所有发布者和订阅者的指针:

template<class incomingDataType, class OutgoingDataType>
class Vertex {
....
bool subscribe(Vertex<OutgoingDataType, __DontCareType__>* subscriber);
OutgoingDataType filter(incomingDataType data) = 0; 
....
//set of 'outgoing vertices' - whom we provide with data
std::set< Vertex<OutgoingDataType, __DontCareType__>* >subscribers_;  
//set of 'incomming vertices' - providing us with data 
std::set< Vertex<__DontCareType__, incomingDataType>* >publishers_; 
}

订阅我们的顶点需要将其传入数据类型与我们的传出数据类型匹配,但我们不关心订阅者的传出数据类型,因为它与我们无关。这同样适用于我们发布者的传入数据类型。

不幸的是,我似乎无法弄清楚如何指定这一点。我已经摆弄了 boost::any (不会编译),void 指针(不会编译),使用函数模板而不是类模板(由于虚拟过滤器功能而无法工作)......但我什么都没有能想到作品。

所以简而言之,我正在寻找一种将“ DontCareType ”类型作为模板参数的方法,如果可能的话,这基本上是一种表达“我标记为'我不在乎的模板参数”的方式' 可以是任何类型,因为无论如何我都不使用它的数据”

作为获得可行解决方案的最后手段,我还在考虑使用一种“VertexData”类型的选项,该类型必须是顶点中使用的任何传入或传出数据类型的基类。这会有帮助吗?

当然也欢迎任何其他使之可行的建议。

4

1 回答 1

3

您想为此使用运行时继承。

template<typename T> struct InputVertex { ... };
template<typename T> struct OutputVertex { ... };
template<typename Incoming, typename Outgoing> struct Vertex 
: public InputVertex<Incoming>, public OutputVertex<Outgoing> {
    std::set<InputVertex<Outgoing>*> outgoings;
public:
    void RegisterFilter(InputVertex<Outgoing>* ptr) {
        outgoings.insert(ptr);
    }
    void RemoveFilter(InputVertex<Outgoing>* ptr) {
        outgoings.erase(ptr);
    }
    void Process(const std::vector<Incoming>& ref) {
        std::vector<Outgoing> output;
        // Transform
        for(auto ref : outgoings) {
            outgoings->Process(output);
        }
    }
};

在这种情况下,传入和传出的接口是明确分开的,这使得两者独立处理变得容易得多。请原谅我使用 C++0x 的基于范围的 for。

于 2011-05-30T13:16:32.760 回答