Информация об изменениях

Сообщение Re[6]: Можно ли записать читабельнее? от 10.04.2023 15:08

Изменено 10.04.2023 15:13 rg45

Re[6]: Можно ли записать читабельнее?
Здравствуйте, Кодт, Вы писали:

К>Так, хорош. Мы щас допилим до продакшена и будем постить в буст или сразу в комитет?


Ну, я уже разогнался, уже легче доехать, чем затормозить

Посмотри, как тебе такой вариант:

http://coliru.stacked-crooked.com/a/718c8e8af7cf764e

template <typename T> concept available = std::is_same_v<T, T>;

template <typename F>
struct callable_wrapper
{
   F f;

   template <typename...X>
   bool operator()(X&&...x) const requires available<decltype(f(std::forward<X>(x)...))> {
      f(std::forward<X>(x)...); return true;
   }

   template <typename...X>
   bool operator()(X&&...) const { return false; }
};

template <typename...F>
auto overloaded(F&&...f)
{
   return [=](auto&&...x) { return (callable_wrapper<F>{f}(x...) || ...); };
}


overloaded — даже не класс, а простейший шаблон функции! Есдинственное отличие — не возникает ошибки компиляции в случае отсутствия обработчика. Таким образом, и пустые цепочки обработчиков тоже возможны. В остальном результат в точности как у тебя.
Re[6]: Можно ли записать читабельнее?
Здравствуйте, Кодт, Вы писали:

К>Так, хорош. Мы щас допилим до продакшена и будем постить в буст или сразу в комитет?


Ну, я уже разогнался, уже легче доехать, чем затормозить

Посмотри, как тебе такой вариант:

http://coliru.stacked-crooked.com/a/718c8e8af7cf764e

template <typename T> concept available = std::is_same_v<T, T>;

template <typename F>
struct callable_wrapper
{
   F f;

   template <typename...X>
   bool operator()(X&&...x) const requires available<decltype(f(std::forward<X>(x)...))> {
      f(std::forward<X>(x)...); return true;
   }

   template <typename...X>
   bool operator()(X&&...) const { return false; }
};

template <typename...F>
auto overloaded(F&&...f)
{
   return [=](auto&&...x) { return (callable_wrapper<F>{f}(x...) || ...); };
}


  Use case
void foo(int x) { printf("foo(%d)\n", x); }
void bar(const char* x) { printf("bar(\"%s\")\n", x); }
void buz(const void* x) { printf("buz(%p)\n", x); }
void def(...) { printf("def(...)\n"); }

int main()
{
   const auto o = overloaded ( &foo, &bar, &buz, &def );

   printf("-----use:-----\n");
   o(123);      // foo
   o("xxx");    // bar
   o(&o);       // baz

   printf("-----misuse:-----\n");
   o(123.45);   // foo
   o(nullptr);  // bar

   printf("-----default:-----\n");
   o(&foo);     // def
   o();         // def
   o(1, 2, 3);  // def
}


overloaded — даже не класс, а простейший шаблон функции! Есдинственное отличие — не возникает ошибки компиляции в случае отсутствия обработчика. Таким образом, и пустые цепочки обработчиков тоже возможны. В остальном результат в точности как у тебя.