Squeak.ru - шаблоны программирования

Как я могу заставить два параметра функции иметь один и тот же тип шаблона?

Я пытаюсь создать реестр, в котором я могу зарегистрировать датчики с соответствующими этапами обработки датчиков.

TLDR: как я могу обеспечить, чтобы два параметра функции имели общий тип параметра/члена шаблона, где оба наследуются от абстрактных классов и могут быть помещены в коллекции, которые принимают любые объекты, производные от этих абстрактных классов?

В идеале я хотел бы иметь что-то вроде этого

// registry
map<string, Sensor> sensors;
map<string, SensorProcessing> processors;

// sensor base class
class Sensor
{
    virtual Data sense();
}

// processing base class
class SensorProcessing
{
    virtual void process(Data d);
}

// data kind base class
struct Data { string name; }

где Sensor и SensorProcessing — абстрактные типы. В идеале коллекция должна принимать любой производный тип датчика или обработки.

Когда я регистрирую датчик и этап обработки, я хотел бы обеспечить, чтобы объект SensorProcessing мог обрабатывать данные, созданные объектом Sensor, с которым он зарегистрирован. Например, не имеет смысла соединять этап обработки изображений с датчиком, который выводит лазерное сканирование.

Что-то вроде этого для регистрации было бы неплохо:

void register_sensor(string name, Sensor s, SensorProcessing p)
{
    // enforce that p eats what s produces, in a typesafe but polymorphic manner
    static_assert(std::is_same<s::data_type, p::data_type>);
}

Но, конечно, это не так просто, потому что аргументы register_sensor() являются базовыми типами, и я не могу во время компиляции проверить, согласуются ли они с используемым типом данных без шаблонов. Однако я не уверен, как это сделать, а также поместить датчики и процессоры в свои собственные иерархии классов.


  • Какую версию С++ вы используете? 09.05.2019
  • В настоящее время 11, но я открыт для предложений с более новыми версиями. 09.05.2019
  • Что ж, если у вас есть возможность, всегда используйте новейший стандарт, то есть С++ 17 атм. 09.05.2019
  • В идеале коллекция должна принимать любой производный тип датчика или обработки. Типы значений карт должны быть указателями базового класса для использования полиморфизма. Что-то вроде map<string, std::unique_ptr<Sensor>> sensors;. Затем вы можете вставить в такую ​​карту указатель на объект любого типа, производного от Sensor. 09.05.2019
  • Вам нужен минимально воспроизводимый пример, описывающий, чего вы хотите достичь. Почему вы не можете передавать полиморфные аргументы в register_sensor? Как определяется тип данных объектов? 09.05.2019
  • Эта часть на самом деле неверна, я уберу ее из вопроса. 09.05.2019
  • Для своей коллекции взгляните на std::variant. Вы можете использовать его как std::variant<std::unique_ptr<Sensor>, std::unique_ptr<SensorProcessing>> и использовать его как тип элемента контейнера. 09.05.2019
  • Проблема с вашей проверкой типов в register_sensor заключается в том, что вы используете полиморфизм времени выполнения для хранения объектов, но хотите проверять время компиляции. Однако это не невозможно, если копия объектов должна быть сохранена (что вы делаете в любом случае, потому что вы передаете значение). 09.05.2019
  • @Timo Да, это загадка, я не уверен, что то, что я хочу, может быть сделано, если только я не добавлю информацию о типе времени выполнения в свои классы, которую я затем могу проверить. Я бы хотел, чтобы компилятор помог мне. 09.05.2019
  • Как ману печатает? Почему карта? 09.05.2019

Ответы:


1

Вы можете проверить тип данных во время компиляции, если создадите указатель внутри вызова функции:

template <typename TSensor, typename TProcessing, typename = std::enable_if_t<std::is_base_of_v<Sensor, TSensor> && std::is_base_of_v<SensorProcessing, TProcessing>>>
void register_sensor(std::string const& name, TSensor s, TProcessing p)
{
    // enforce that p eats what s produces, in a typesafe but polymorphic manner
    static_assert(std::is_same_v<typename TSensor::data_type, typename TProcessing::data_type>, "Data type missmatch");

    // create the pointers here and move s and p in
}

Обратите внимание, что это создаст копию объектов Sensor и SensorProcessing, которые вы передаете.

Вот возможная реализация. Я не уверен, чего вы пытаетесь достичь с помощью контейнера, который вы описали, поэтому я выбрал тот, который имеет смысл с моей точки зрения.

09.05.2019

2

Есть несколько вариантов.

  • Используйте IDispatch или что-то вроде что если не под виндой
  • Используйте std::any (C++ 17)
  • Используйте интерфейсы на основе COM, регистрацию COM и библиотеку типов, чтобы справиться со всем тем, что уже сделано за вас.
  • Используйте сериализуемые объекты в распространенных форматах (JSON, XML).
09.05.2019
Новые материалы

Угловая структура архитектуры
Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

«Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

Создайте API с помощью Python FastAPI
Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

Веселье с прокси-сервером JavaScript
Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...