Шаблон функции, который позволил бы применять заданную функцию многократно

Пусть надо написать шаблонную функцию такого вида.

deep<func, 2>(1);    // func(func(1))
template<auto foo, size_t depth, typename... Args>
auto deep(Args&&... args)
{
    ...
    auto result = deep<foo, depth - 1>(std::forward<Args>(args)...);
    ...
    return result;
}

Тут напрашивается еще одна шаблонная функция deep с частичной специализацией, которая бы просто вызывала исходную функцию. Что-то по типу

template<auto foo, size_t depth = 0, typename... Args>
auto deep(Args... args)
{
    return foo(std::forward<Args>(args)...);
}

Но в c++ нет частичной специализации шаблонной функции. Можно ли это как-то обойти, не используя классы?


Ответы (1 шт):

Автор решения: Harry

Можно что-то типа

template<size_t depth, typename Func, typename... Args>
auto deep(Func foo, Args&&... args)
{
    if constexpr(depth != 0)
        return foo(deep<depth-1>(foo, std::forward<Args>(args)...));
    else
        return foo(std::forward<Args>(args)...);
}

Так сойдет?

Только вот как по мне, Args...args излишне, ибо второй и последующие вызовы foo применяются к единственному аргументу, каковой одновременно является и возвращаемым типом (или приводимым).

Да и разворот во время компиляции мне кажется излишним. Вот так не хотите?

template<typename Func, typename Arg>
auto deep(size_t depth, Func foo, Arg arg)
{
    auto res = foo(arg);
    for(;depth-->0;res = foo(res));
    return res;
}
→ Ссылка