Как проверить, что два вложенных варианта имеют один и тот же тип ⇐ C++
-
Гость
Как проверить, что два вложенных варианта имеют один и тот же тип
Код использует вложенные std::variant для моделирования сообщений:
класс A{}; класс Б{}; класс С{}; класс Д{}; используя CMD1 = std::variant; используя CMD2 = std::variant; используя CMD = std::variant; Чтобы отправлять сообщения нужным актерам, актеры определяют общедоступный список типов со всеми типами команд, которые они хотят получать:
struct ActorAC { использование handleable = typelist; }; структура ActorBD { использование handleable = typelist; }; Во время выполнения планировщик получает команду — типом является вариант, инкапсулирующий все остальные подварианты, затем он проверяет, находится ли конкретный тип команды внутри typelist< актеров. /code>, если это так, он отправляет сообщение актеру:
CMD cmd = get_cmd(); //это то, что я хотел бы сделать if (is_any(get_concrete_type(cmd), actAC::handleables)){ // отправляем сообщение в actAC } if (is_any(get_concrete_type(cmd),actorBD::handleables)) { //отправляем сообщение актеру BD } получить текущий элемент варианта возможно только с помощью visit, поэтому давайте попробуем: напишем функцию, которая проверит, является ли данный тип одним из конкретных типов варианта: шаблон constexpr bool is_concrete(std::variant v) { вернуть std::visit(Overload{ [](HandelableType) { /*это тот же тип! законченный*/ вернуть истину; }, [](std::variant vin) { /* до листовых вариантов мы так и не дошли*/ return is_in_concrete(vin); }, [](авто) { /* если это не вариант и не наш тип - наверняка это не то, что нам нужно*/ вернуть ложь; }, }, в); } попробуем использовать:
int main(){ CMD cmd(A()); //должен скомпилироваться и вернуть true вернуть is_concrete(cmd); } но я получаю эту ошибку от g++-13:
ошибка: нет соответствующей функции для вызова is_concrete
примечание: шаблон-кандидат игнорируется: не удалось сопоставить 'std::variant' с 'std::variant ()(A)' (он же 'variant ()(A)')
Итак, при первом вызове из main компилятор не соответствует — что происходит??
в идеале это было бы так:
шаблон bool mustActUpon(CMD cmd) { return (is_concrete(cmd) || ...); } вот полный файл:
#include шаблон struct Overload : Ts... { используя Ts::operator()...; }; шаблон Overload(Ts...) -> Overload; класс А {}; класс Б {}; класс С {}; класс Д {}; используя V1 = std::variant; используя V2 = std::variant; используя V = std::variant; шаблон constexpr bool is_concrete(std::variant cmd) { вернуть std::visit(Overload{ [&](HandlableType) { /*v1 — вариант рекурсивного вызова индекса*/ вернуть истину; }, [&](std::variant vin) { return is_concrete(vin); }, [](авто) { /*v1 не является вариантом — оба имеют один и тот же тип, *тот же индекс и лист*/ вернуть истину; }, }, cmd); } интервал основной() { В смд(А); is_concrete(cmd); }
Код использует вложенные std::variant для моделирования сообщений:
класс A{}; класс Б{}; класс С{}; класс Д{}; используя CMD1 = std::variant; используя CMD2 = std::variant; используя CMD = std::variant; Чтобы отправлять сообщения нужным актерам, актеры определяют общедоступный список типов со всеми типами команд, которые они хотят получать:
struct ActorAC { использование handleable = typelist; }; структура ActorBD { использование handleable = typelist; }; Во время выполнения планировщик получает команду — типом является вариант, инкапсулирующий все остальные подварианты, затем он проверяет, находится ли конкретный тип команды внутри typelist< актеров. /code>, если это так, он отправляет сообщение актеру:
CMD cmd = get_cmd(); //это то, что я хотел бы сделать if (is_any(get_concrete_type(cmd), actAC::handleables)){ // отправляем сообщение в actAC } if (is_any(get_concrete_type(cmd),actorBD::handleables)) { //отправляем сообщение актеру BD } получить текущий элемент варианта возможно только с помощью visit, поэтому давайте попробуем: напишем функцию, которая проверит, является ли данный тип одним из конкретных типов варианта: шаблон constexpr bool is_concrete(std::variant v) { вернуть std::visit(Overload{ [](HandelableType) { /*это тот же тип! законченный*/ вернуть истину; }, [](std::variant vin) { /* до листовых вариантов мы так и не дошли*/ return is_in_concrete(vin); }, [](авто) { /* если это не вариант и не наш тип - наверняка это не то, что нам нужно*/ вернуть ложь; }, }, в); } попробуем использовать:
int main(){ CMD cmd(A()); //должен скомпилироваться и вернуть true вернуть is_concrete(cmd); } но я получаю эту ошибку от g++-13:
ошибка: нет соответствующей функции для вызова is_concrete
примечание: шаблон-кандидат игнорируется: не удалось сопоставить 'std::variant' с 'std::variant ()(A)' (он же 'variant ()(A)')
Итак, при первом вызове из main компилятор не соответствует — что происходит??
в идеале это было бы так:
шаблон bool mustActUpon(CMD cmd) { return (is_concrete(cmd) || ...); } вот полный файл:
#include шаблон struct Overload : Ts... { используя Ts::operator()...; }; шаблон Overload(Ts...) -> Overload; класс А {}; класс Б {}; класс С {}; класс Д {}; используя V1 = std::variant; используя V2 = std::variant; используя V = std::variant; шаблон constexpr bool is_concrete(std::variant cmd) { вернуть std::visit(Overload{ [&](HandlableType) { /*v1 — вариант рекурсивного вызова индекса*/ вернуть истину; }, [&](std::variant vin) { return is_concrete(vin); }, [](авто) { /*v1 не является вариантом — оба имеют один и тот же тип, *тот же индекс и лист*/ вернуть истину; }, }, cmd); } интервал основной() { В смд(А); is_concrete(cmd); }
Мобильная версия