Мне интересно, если существует некий механизм, позволяющий мне взять некоторый список типов, предоставленных пользователем, и зарегистрировать их, создав вариант 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
Мобильная версия