Возможна ли шаблонная версия виртуального базового класса в качестве интерфейса во время компиляции?C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Возможна ли шаблонная версия виртуального базового класса в качестве интерфейса во время компиляции?

Сообщение Anonymous »


Я работаю над структурой для системного проектирования на основе моделей (MBSE). Здесь у меня есть конструкция под названием Bridge. Мост может отправлять Сигналы (асинхронные вызовы) и/или Операции (синхронные вызовы) с одного конца Моста на другой. Сигналы и операции также могут иметь полезную нагрузку, определенную конечным пользователем платформы (другим программистом на C++).

Мост подключен к сети, поэтому вход моста подключается к выходу моста через сетевой сокет. Чтобы это работало, необходимо сериализовать сигналы и/или операции (сокращенно SigOps), а также возможную полезную нагрузку.

У моста есть исходящая очередь, которая буферизует и сохраняет последовательность SigOp по мере их выдачи. Следовательно, эта очередь хранит SigOps, используя общие указатели SigOp. Но все равно необходимо использовать специальный сериализатор типа SigOp.

Обычный способ сделать это — использовать виртуальный базовый класс, определяющий интерфейс, а затем позволить производному классу добавить реализацию. Что-то вроде:

// Виртуальный базовый класс/интерфейс SigOp, специфичный для типа моста шаблон класс СигОпТ { публика: виртуальная пустота initSerialization (SigOpSerDes &fSerializer, SerializationBuffer &fSerializationBuffer) = 0; виртуальная пустота сериализоватьPayLoad (SigOpSerDes &fSigOpSerializer) = 0; }; шаблон класс MySigOp: public SigOpT { void initSerialization(SigOpSerDes &fSerializer, SerializationBuffer &fSerializationBuffer) переопределить окончательный вариант { // Моя реализация ... } voidserializePayLoad(SigOpSerDes &fSigOpSerializer) переопределенный финал { // Мой код сериализации, специфичный для MySigOp ... } }; На вопрос: Есть ли способ сделать то же самое во время компиляции, исключив тем самым виртуальные функции, виртуальные таблицы и т. д.?

CRTP (https://en.wikipedia.org/wiki/Curiious_ ... te_pattern) не работает, поскольку при этом будет удален общий базовый класс/тип интерфейса, который может храниться в очереди Bridge.

шаблон класс База { } Производный класс: Base { } Я также рассматривал std::variant как способ хранения различных типов SigOp в очереди, но в настоящее время я привязан к C++-14 (std::variant появился в C++-17). Кроме того, вариант std::variant, который может хранить все типы SigOp Bridge, а также их возможные полезные нагрузки, будет занимать много памяти (если я не ошибаюсь).

На данный момент у меня есть кусочки, но я не нашел способа склеить их все вместе. Шаблон моста:

шаблон класс BridgeT { // Ставим сигнал в очередь для последующей сериализации и транспортировки по сети с помощью ZMQ шаблон встроенный статический void-пост (const tSignalType &fSignal) { /** * Здесь я знаю все типы, необходимые для полного определения того, как должна выполняться сериализация. * * Таким образом: * * tBridgeDeclType — тип объявления моста. Магазины этого типа * отношения к типам ниже. * * typename tBridgeDeclType::SigOpTypes — std::tuple со списком всех типов SigOp * поддерживается мостом * * tSignalType — конкретный тип SigOp (в данном случае сигнал), который нам нужен. * для постановки в мосты исходящей очереди SigOp (см. ниже). * * Эта настройка в фоновом режиме обеспечивает безопасность типов, поэтому только SigOps * явная поддержка конкретного типа моста может быть опубликована и передана *у моста. Использование неподдерживаемого SigOps приводит к ошибке компиляции. */ // Как совместить это со специфичным для типа SigOp // SerializableSigOpT все еще может использовать // Тип слота очереди SigOp, общий для моста? // Ставим в очередь SigOp очередь.push(fSignal); } статическая очередь std::queue; }; И шаблон сериализатора SigOp, который перенаправляет на правильный код сериализации во время компиляции:

шаблон класс SerializableSigOpT: public SigOpT { публика: inline static void initSerialization(SigOpSerDes &fSigOpSerializer, const SigOpSeqNumType fSeqNumber, SerializationBuffer &fSerBuffer) { fSigOpSerializer.initSerialization(getSigOpTypeIdT::cId, fSeqNumber, fSerBuffer); } встроенная статическая сила сериализацииPayLoad (const tSigOpType &fSigOp, SigOpSerDes &fSigOpSerializer) { // Сериализуем полезную нагрузку, если она существует. Это условный шаблон, который не компилируется без кода, когда у SigOp нет полезной нагрузки. PayLoadSerDesT::serializePayLoad(fSigOp, fSigOpSerializer); } }; Можно ли это сделать, используя шаблоны C++, или это одна из тех вещей, которые на первый взгляд кажутся такими простыми, но когда вы вникаете в детали, появляется дьявол???

/Нильс
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»