Я определил класс вершин, которые при объединении образуют граф. эти вершины получают входные данные на одном конце и производят выходные данные на другом (обе эти стороны могут иметь 0, 1 или более «подписок» на другие экземпляры этого класса вершин). Типы как для входящих, так и для исходящих данных не зависят друг от друга. other и указываются как параметры шаблона, поскольку эти вершины должны работать со всеми типами ввода/вывода.
Итак, в коде это становится:
template<class incomingDataType, class OutgoingDataType>
class Vertex {...}
Перед отправкой полученных данных вершина может применить функцию фильтра для преобразования/фильтрации данных перед их повторной отправкой своим подписчикам списка. Эта функция объявлена как чисто виртуальная функция, поскольку ее функциональность зависит от типа класса специализации, наследуемого от этого базового класса виртуальной вершины.
Это означает, что фильтр объявлен как:
OutgoingDataType filter(incomingDataType data) = 0;
Конечно, я хочу связать несколько вершин друг с другом. Рассмотрим это связывание в его самой простой форме, когда вход и выход каждой вершины связаны ровно с одним входом/выходом другой вершины:
(ClassX)vertex1(int) --> (int)vertex2(std::string) --> (std::string)vertex3(OtherClassOrType) -->...
Имея это в виду, постановка задачи для данного примера выглядит следующим образом:
вершина 2 должна указать вершину 1 в качестве подписчика и подписаться на вершину 3. Чтобы отслеживать все эти подписки, вершина хранит набор указателей на всех своих издателей и подписчиков:
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», который должен быть базовым классом любых входящих или исходящих типов данных, используемых в вершинах. Будет ли это чем-то помочь?
Любые другие предложения по реализации этого, конечно же, также приветствуются.