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

Сообщение Re[2]: Можно ли записать читабельнее? от 08.04.2023 11:35

Изменено 08.04.2023 17:26 rg45

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

К>в развитие темы: если С++20 и концепты/констрейны, то

К>

К>template<class T> concept has_foo = requires (T t) { t.foo(0); };
К>template<class T> concept has_bar = requires (T t) { t.bar(""); };

К>....
К>visit(your_tuple,
К>  overloaded{
К>    [](auto t) requires has_foo<std::decay_t<decltype(t)>> { t.foo(123); },
К>    [](auto t) requires has_bar<std::decay_t<decltype(t)>> { t.bar("hello"); },
К>    [](auto t) { },  // без констрейнов имеет меньший приоритет, чем с констрейнами
К>  }
К>);
К>


Здесь можно обойтись одним общим концептом и избавиться от необходимости определять концепты для каждой функции-члена в отдельности:

http://coliru.stacked-crooked.com/a/04c2c65eca5b3115

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

int main()
{
    visit(std::make_tuple(HasFoo{}, HasBar{}, HasNothing{}),
        overloaded {
            [](auto&& t) requires available<decltype(t.foo())> { t.foo(); },
            [](auto&& t) requires available<decltype(t.bar())> { t.bar(); },
            [](auto&& t) { std::cout << "Has neither foo nor bar" << std::endl; }
        }
    );
}


И эллипсис ушел, и фейковых параметров не требуется, и пространсва имен не засоряются лишними концептами, и достаточно читабельно, как по мне.
Re[2]: Можно ли записать читабельнее?
Здравствуйте, Кодт, Вы писали:

К>в развитие темы: если С++20 и концепты/констрейны, то

К>

К>template<class T> concept has_foo = requires (T t) { t.foo(0); };
К>template<class T> concept has_bar = requires (T t) { t.bar(""); };

К>....
К>visit(your_tuple,
К>  overloaded{
К>    [](auto t) requires has_foo<std::decay_t<decltype(t)>> { t.foo(123); },
К>    [](auto t) requires has_bar<std::decay_t<decltype(t)>> { t.bar("hello"); },
К>    [](auto t) { },  // без констрейнов имеет меньший приоритет, чем с констрейнами
К>  }
К>);
К>


Здесь можно обойтись одним общим концептом и избавиться от необходимости определять концепты для каждой функции-члена в отдельности:

http://coliru.stacked-crooked.com/a/ef1cd277644570b2

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

int main()
{
    visit(std::make_tuple(HasFoo{}, HasBar{}, HasNothing{}),
        overloaded {
            [](auto&& t) requires available<decltype(t.foo())> { t.foo(); },
            [](auto&& t) requires available<decltype(t.bar())> { t.bar(); },
            [](auto&& t) { std::cout << "Has neither foo nor bar" << std::endl; }
        }
    );
}


И эллипсис ушел, и фейковых параметров не требуется, и пространсва имен не засоряются лишними концептами, и достаточно читабельно, как по мне.