Re[6]: std::get(std::variant)
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 23.10.25 19:59
Оценка:
Здравствуйте, rg45, Вы писали:

M>>Просто и понятно.


R>Ну и чем это проще и понятнее, чем:


R>https://coliru.stacked-crooked.com/a/83124dc3a3facc5d


R>
R>int func(MyVariant v)
R>{
R>    return std::visit([]<typename T>(const T& t) {
R>        if constexpr (std::same_as<T, A>)
R>        {
R>            doSomething(t);
R>        }
R>        else if constexpr (std::same_as<T, B> or std::same_as<T, C>)
R>        {
R>            std::cout << "Error: B or C not allowed here\n";
R>            return -1;
R>        }
R>        return 0; // OK
R>    }, v);
R>}
R>


в ветке doSomething(t); я не хочу выходить из func. Надо было там написать после if продолжение кода — //.... Поправлю для остальных


R>И это не единственный, и не лучший, кстати, вариант использования — тут на перегрузках можно реально по красоте всё сделать.


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


Генератор

А можно в рантайме, в какой-нибудь другой подсистеме, сформировать список альтернатив, которые нужно обработать, и передать в обработчик вместе с variant'ом?
Маньяк Робокряк колесит по городу
Re[7]: std::get(std::variant)
От: rg45 СССР  
Дата: 23.10.25 20:00
Оценка:
Здравствуйте, Marty, Вы писали:

M>Генератор


Ну так если генератор, тогда не понятно, зачем было эту тему создавать.
--
Справедливость выше закона. А человечность выше справедливости.
Re[8]: std::get(std::variant)
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 23.10.25 20:02
Оценка:
Здравствуйте, rg45, Вы писали:

M>>у нас намечается простыня


R>Так это только благодаря тебе она начинается, потому что ты if-ы используешь. А так-то вообще такие штуки на перегрузках делаются. И перегрузки можно делать по-разному. Можно, лямбды использовать, можно собственные функционалы. Можно через композицию, можно через монолиты. И здесь очень востребованы оказываются концепцы и констрейнты. И код реально выглядит красиво и профессионально, не что что твои if-ы, с энумами.


Нет под рукой ссылки, где можно почитать такой прекрасный код?
Маньяк Робокряк колесит по городу
Re[7]: std::get(std::variant)
От: rg45 СССР  
Дата: 23.10.25 20:04
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте, rg45, Вы писали:


M>>>Просто и понятно.


R>>Ну и чем это проще и понятнее, чем:


R>>https://coliru.stacked-crooked.com/a/83124dc3a3facc5d


R>>
R>>int func(MyVariant v)
R>>{
R>>    return std::visit([]<typename T>(const T& t) {
R>>        if constexpr (std::same_as<T, A>)
R>>        {
R>>            doSomething(t);
R>>        }
R>>        else if constexpr (std::same_as<T, B> or std::same_as<T, C>)
R>>        {
R>>            std::cout << "Error: B or C not allowed here\n";
R>>            return -1;
R>>        }
R>>        return 0; // OK
R>>    }, v);
R>>}
R>>


M>в ветке doSomething(t); я не хочу выходить из func. Надо было там написать после if продолжение кода — //.... Поправлю для остальных


Так просто убери else после if-а и пиши, что хочешь. Я же опирался на твой прототип.
--
Справедливость выше закона. А человечность выше справедливости.
Re[8]: std::get(std::variant)
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 23.10.25 20:11
Оценка:
Здравствуйте, rg45, Вы писали:

R>>>
R>>>    return std::visit([]<typename T>(const T& t) {
R>>>


О, шаблонная лямбда? Не встречал такого. Через жопу писал (auto a) и затем тип выводил через declspec/decay


M>>в ветке doSomething(t); я не хочу выходить из func. Надо было там написать после if продолжение кода — //.... Поправлю для остальных


R>Так просто убери else после if-а и пиши, что хочешь. Я же опирался на твой прототип.


Ну, может ты и прав.

А где бы всё же полюбоваться на божественный код с variant'ами? Для общего развития?

И как списки альтернатив передавать между подсистемами в рантайме?
Маньяк Робокряк колесит по городу
Re[9]: std::get(std::variant)
От: rg45 СССР  
Дата: 23.10.25 20:19
Оценка:
Здравствуйте, Marty, Вы писали:

M>Нет под рукой ссылки, где можно почитать такой прекрасный код?


Ну вот этот
Автор: Marty
Дата: 23.10 22:11
твой пример, без особого труда мог бы выглятеть как-то вот так:

void func(MyVariant v)
{
  return MyVisit(v,    
    [](const A& a) {
      doSomething(a);
      return 1;
    },
    [](const AnyTypeOfList<B, C> auto&) {
      log << "Error: B or C not allowed here not allowed here\n";
      return -1;
    },
    [](const auto&) {
      return 0; // OK
    }
  );
}


Прекрасно, не прекрасно, но по-любому лучше, чем твои if-ы с энумами, я считаю.
--
Справедливость выше закона. А человечность выше справедливости.
Re[9]: std::get(std::variant)
От: rg45 СССР  
Дата: 23.10.25 20:21
Оценка:
Здравствуйте, Marty, Вы писали:

M>А где бы всё же полюбоваться на божественный код с variant'ами? Для общего развития?


Вот, любуйся: https://rsdn.org/forum/cpp/9009026.1
Автор: rg45
Дата: 23.10 23:19


Рабочие примеры, я уже задолбался писать, честно говоря. Но поверь, для того, чтобы добиться такого, требуется всего пол экрана вспомогательного повторно используемого кода.
--
Справедливость выше закона. А человечность выше справедливости.
Re[10]: std::get(std::variant)
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 23.10.25 20:33
Оценка:
Здравствуйте, rg45, Вы писали:

R>Ну вот этот
Автор: Marty
Дата: 23.10 22:11
твой пример, без особого труда мог бы выглятеть как-то вот так:


R>
R>void func(MyVariant v)
R>{
R>  return MyVisit(v,    
R>    [](const A& a) {
R>      doSomething(a);
R>      return 1;
R>    },
R>    [](const AnyTypeOfList<B, C> auto&) {
R>      log << "Error: B or C not allowed here not allowed here\n";
R>      return -1;
R>    },
R>    [](const auto&) {
R>      return 0; // OK
R>    }
R>  );
R>}
R>


А как выглядит MyVisit?


R>Прекрасно, не прекрасно, но по-любому лучше, чем твои if-ы с энумами, я считаю.


Ну, может и лучше.

Но я сейчас в жоском эмбеде, проект на чистой сишечке.
Я пилю вспомогательную тулзу
Автор: Marty
Дата: 13.09 17:25
на плюсах, разбираю сишечную метадату через CastXML. В принципе, уже сделал на говне, решил разобраться, как можно было бы сделать лучше. И да, мои if/else/switch для поддержки были бы гораздо проще кому-то из команды кроме меня.

ЗЫ А в частном порядке нельзя с тобой связаться, если ты не против? А то код проекта не могу показывать на публику, но в частном порядке думаю можно. А ты бы мог без труда найти дерьмовые решения, и показать на форуме только их, чтобы всем было полезно.
Наверное, нахрен тебе не надо
Маньяк Робокряк колесит по городу
Отредактировано 23.10.2025 20:34 Marty . Предыдущая версия .
Re[10]: std::get(std::variant)
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 23.10.25 20:34
Оценка:
Здравствуйте, rg45, Вы писали:

R>я уже задолбался писать


Ну извини
Маньяк Робокряк колесит по городу
Re[11]: std::get(std::variant)
От: rg45 СССР  
Дата: 23.10.25 20:36
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте, rg45, Вы писали:


R>>Ну вот этот
Автор: Marty
Дата: 23.10 22:11
твой пример, без особого труда мог бы выглятеть как-то вот так:


R>>
R>>void func(MyVariant v)
R>>{
R>>  return MyVisit(v,    
R>>    [](const A& a) {
R>>      doSomething(a);
R>>      return 1;
R>>    },
R>>    [](const AnyTypeOfList<B, C> auto&) {
R>>      log << "Error: B or C not allowed here not allowed here\n";
R>>      return -1;
R>>    },
R>>    [](const auto&) {
R>>      return 0; // OK
R>>    }
R>>  );
R>>}
R>>


M>А как выглядит MyVisit?


Эскизно примерно вот так:

decltype(auto) MyVisit(auto&& t, Callable auto&&...f)
{
   return std::visit(Overloaded(f...), v);
}
--
Справедливость выше закона. А человечность выше справедливости.
Re[11]: std::get(std::variant)
От: rg45 СССР  
Дата: 23.10.25 20:40
Оценка:
Здравствуйте, Marty, Вы писали:

M>ЗЫ А в частном порядке нельзя с тобой связаться, если ты не против? А то код проекта не могу показывать на публику, но в частном порядке думаю можно. А ты бы мог без труда найти дерьмовые решения, и показать на форуме только их, чтобы всем было полезно.

M>Наверное, нахрен тебе не надо

Можно. Только не сегодня, ладно?

Я сделаю все необходимые вспомогательные утилиты (благо их не так уж много), а ты придумай какой-нибудь синтетический, не очень сложный, но более-менее осмысленный пример, на котором можно будет обкатать. И выкладывай пример прямо сюда. Я на днях по свободке запилю.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 23.10.2025 20:45 rg45 . Предыдущая версия . Еще …
Отредактировано 23.10.2025 20:41 rg45 . Предыдущая версия .
Re[3]: std::get(std::variant)
От: rg45 СССР  
Дата: 23.10.25 20:44
Оценка:
Здравствуйте, Marty, Вы писали:

M>
M>auto kind = getKind(v);
M>name = getName(kind, v);
M>


M>Как мне такое сделать?


Да выброси ты свои kind-ы, это вчерашний день. Ты ж пойми, эти кайнды тебе нужны только для того, чтобы сделать диспетченизацию и полиморфизм. Больше ни зачем.
--
Справедливость выше закона. А человечность выше справедливости.
Re[4]: std::get(std::variant)
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 23.10.25 20:49
Оценка:
Здравствуйте, rg45, Вы писали:

M>>Как мне такое сделать?


R>Да выброси ты свои kind-ы, это вчерашний день. Ты ж пойми, эти кайнды тебе нужны только для того, чтобы сделать диспетченизацию и полиморфизм. Больше ни зачем.


В целом, я понимаю, но современный сипипи много шума даёт, пытаюсь найти вариант, который бы использовал современный язык, но был бы прост для поддержки
Маньяк Робокряк колесит по городу
Re[3]: std::get(std::variant)
От: YuriV  
Дата: 23.10.25 21:37
Оценка:
Здравствуйте, Marty, Вы писали:

Можно так:

template<typename ... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<typename ... Ts> overloaded(Ts...) -> overloaded<Ts...>;

// use concept if liked
template <typename T> concept has_name = 
    requires(T a) {{a.name}->std::convertible_to<std::string>;};

// ...
if(k==kind)
  return std::visit(overloaded{
      [](auto && t) -> std::string requires requires {{t.name} -> std::convertible_to<std::string>;}  { return t.name; }
      , [](auto && t) -> std::string requires (not requires {{t.name} -> std::convertible_to<std::string>;}) { return {}; }
  }, v);


здесь
Re[5]: std::get(std::variant)
От: so5team https://stiffstream.com
Дата: 24.10.25 05:04
Оценка:
Здравствуйте, Marty, Вы писали:

S>>Вы специально проигнорировали цитату про второй вариант std::get-а?


M>Да


Да уж. "Если факты не согласуются с нашей точкой зрения, то тем хуже для фактов".
Re[3]: std::get(std::variant)
От: so5team https://stiffstream.com
Дата: 24.10.25 05:07
Оценка:
Здравствуйте, Marty, Вы писали:

M>
M>    return getNameImpl(kind, x, {Kind::A, Kind::B, ...});
M>


M>Ну или как-то так


Простите, а вот этот вот список {Kind::A, Kind::B, ...} -- он откуда возьмется?
Его программист должен ручками написать? Типа "я помню, что в структуре A есть атрибут name, поэтому Kind::A нужно включить в этот список". Правильно?
Re[4]: std::get(std::variant)
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 24.10.25 06:50
Оценка:
Здравствуйте, so5team, Вы писали:

M>>
M>>    return getNameImpl(kind, x, {Kind::A, Kind::B, ...});
M>>


M>>Ну или как-то так


S>Простите, а вот этот вот список {Kind::A, Kind::B, ...} -- он откуда возьмется?

S>Его программист должен ручками написать? Типа "я помню, что в структуре A есть атрибут name, поэтому Kind::A нужно включить в этот список". Правильно?

Типа того. Но в моей задаче я разбирал XML, можно было оттуда выцепить и сгенерить код
Маньяк Робокряк колесит по городу
Re[5]: std::get(std::variant)
От: so5team https://stiffstream.com
Дата: 24.10.25 07:03
Оценка:
Здравствуйте, Marty, Вы писали:

S>>Простите, а вот этот вот список {Kind::A, Kind::B, ...} -- он откуда возьмется?

S>>Его программист должен ручками написать? Типа "я помню, что в структуре A есть атрибут name, поэтому Kind::A нужно включить в этот список". Правильно?

M>Типа того. Но в моей задаче я разбирал XML, можно было оттуда выцепить и сгенерить код


Ну так говно же.

Современный C++ позволяет сделать это проще. Выше тов.YuriV уже показал набросок.
Re[4]: std::get(std::variant)
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 24.10.25 07:39
Оценка:
Здравствуйте, YuriV, Вы писали:

YV>Можно так:


YV>
YV>template<typename ... Ts> struct overloaded : Ts... { using Ts::operator()...; };
YV>template<typename ... Ts> overloaded(Ts...) -> overloaded<Ts...>;

YV>// use concept if liked
YV>template <typename T> concept has_name = 
YV>    requires(T a) {{a.name}->std::convertible_to<std::string>;};

YV>// ...
YV>if(k==kind)
YV>  return std::visit(overloaded{
YV>      [](auto && t) -> std::string requires requires {{t.name} -> std::convertible_to<std::string>;}  { return t.name; }
YV>      , [](auto && t) -> std::string requires (not requires {{t.name} -> std::convertible_to<std::string>;}) { return {}; }
YV>  }, v);
YV>


YV>здесь


Спасибо, поизучаю. Но я бы не сказал, что это всё очень просто
Маньяк Робокряк колесит по городу
Re[5]: std::get(std::variant)
От: so5team https://stiffstream.com
Дата: 24.10.25 07:57
Оценка: +1
Здравствуйте, Marty, Вы писали:

YV>>здесь


M>Спасибо, поизучаю. Но я бы не сказал, что это всё очень просто


ИМХО, вот так гораздо проще: https://godbolt.org/z/YW839hjGY
Но идея та же самая.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.