Зарегистрируйте типы для std::variant программноC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Зарегистрируйте типы для std::variant программно

Сообщение Anonymous »

Рассмотрите следующий листинг кода и представьте, что я пишу библиотеку, которая содержит все, начиная со строки using Event. Любой пользователь моей библиотеки будет создавать свои собственные типы событий и типы состояний. Мое единственное требование — чтобы они предоставляли методы входа и выхода для своих типов состояний, которые соответствуют событиям, которые могут вызвать их переход.
Мне интересно, если существует некий механизм, позволяющий мне взять некоторый список типов, предоставленных пользователем, и зарегистрировать их, создав вариант std::variant с использованием этих типов.
Другими словами, я не могу знать, что типы, которые пользователь предоставит мне во время написания библиотеки, но они должны быть известны во время компиляции.

Код: Выделить всё

#include 
#include 
#include 

struct PedCrossingEvent{int m_myCustomUseData};
struct ProgramTimeElapsedEvent{double m_myOtherUserCustomData};
struct NoProgramEvent{std::string m_otherDataStill};

class Elephant;

struct GreenState
{
Elephant * m_customStateData;

void enter(std::shared_ptr
 predCrossingEvent)
{
if (predCrossingEvent.m_myCustomUseData > 10)
{//...}
}

void enter(std::shared_ptr programTimeElapsedEvent)
{
if( programTimeElapsedEvent.m_myOtherUserCustomData < 100.0 )
{//...}
}

void enter(std::shared_ptr noProgramEvent)
{
if( noProgramEvent.m_otherDataStill< 100.0 )
{//...}
}

void exit(std::shared_ptr pedCrossingEvent)
{}

void exit(std::shared_ptr programTimeElapsedEvent)
{}

void exit(std::shared_ptr noProgramEvent)
{}
};

// How do I, at compile time, register user defined types from above, that could be anything the user dreams up, with this variant in my library?
// I need some kind of "register type" compile time mechanism
using Event = std::variant;

int main()
{
std::vector events = {
std::make_shared(),
std::make_shared(),
std::make_shared()
};

GreenState green;
std::visit([&green](auto&& arg) { green.enter(arg); }, events[0]);

return 0;
}
Я не хочу слишком углубляться в дизайн и назначение библиотеки, поскольку это быстро уводит от темы, но просто чтобы помочь понять концепцию, которую я Я хочу лучшего...Мои собственные требования:
  • Пользователь может указать любое количество собственных типов (событий)
  • Пользователь может указать любое количество своих типов (состояний)
  • Позже я создам некоторый метод регистрации, чтобы пользователь мог сообщать мне о своих событиях, состояниях и о том, какие события вызывают переходы из какого состояния в какое.
  • Мне нужно иметь возможность помещать эти типы (события) в одну коллекцию
  • Мне нужно иметь возможность вызывать методы других пользовательских типов (состояний), используя первую коллекцию типов, которые они дали мне в качестве параметров (событий)
  • Я отчаянно пытаюсь избежать классического наследования с динамическим приведением к получить конкретные типы, предоставленные пользователем.
Объяснил еще один способ, еще для ясности (с учетом комментариев):
Что мне нужно, так это возможность выполнять обратные вызовы с использованием пользовательских типов и их пользовательских типов, чтобы пользователь мог получать любые данные, которые он добавил в свои пользовательские типы.
В 1990 году я бы делал это с базовыми классами, из которых пользователь извлекает состояния и события, заставлял их помещать свои пользовательские данные в конкретные классы, давал бы мне какой-нибудь механизм typeid, регистрировал бы их типы с помощью моя библиотека использует эти идентификаторы типов, а затем выполняет для них динамическое приведение типов, когда придет время выполнять обратные вызовы, но я хочу этого избежать.
Люди будут ругаться, «если вы используете динамический_cast ты делаешь что-то неправильно». Ок, отлично. Давайте посмотрим, как их сделать правильно. Я считаю, что это утверждение применимо к методам, а не к данным, и особенно к данным, типы которых заранее неизвестны.

Подробнее здесь: https://stackoverflow.com/questions/785 ... amatically
Ответить

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

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

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

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

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