C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::recurse

From: Pavel Vazharov <freakpv_at_[hidden]>
Date: Thu, 15 May 2025 16:16:46 +0300
On Thu, May 15, 2025 at 4:10 PM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:

> Here's a recursive function:
>
> unsigned Factorial(unsigned const n)
> {
> if ( 1u == n ) return 1u;
> return n * Factorial(n - 1u);
> }
>
> If we were to have a standard library function called "std::recurse",
> then we could rewrite the above function as:
>
> unsigned Factorial(unsigned const n)
> {
> if ( 1u == n ) return 1u;
> return n * std::recurse(n - 1u);
> }
>
> This might make things a little more convenient when making a minimal
> revision to an SVN or Github repo (i.e. you only have to edit one line
> if you change the name of the function). It would also be more
> convenient for code generation tools in that they don't have to keep
> track of the name of the function -- but of course these two benefits
> are no big deal.
>
> Here is how people are currently writing recursive lambdas:
>
> #include <iostream>
> #include <functional>
>
> int main(int const argc, char **const argv)
> {
> std::function<void(int)> func =
> [&func,argv](int const count)
> {
> if ( 0 == count ) return;
> std::cout << argv[count - 1] << std::endl;
> func(count - 1);
> };
>
> func(argc);
> }
>
> There isn't any way to pull this off without using "std::function".
> However, if C++29 were to have "std::recurse", then we could do:
>
> #include <iostream>
>
> int main(int const argc, char **const argv)
> {
> auto func = [argv](int const count)
> {
> if ( 0 == count ) return;
> std::cout << argv[count - 1] << std::endl;
> std::recurse(count - 1);
> };
>
> func(argc);
> }
>
C++23 is enough to cover you here <https://godbolt.org/z/cGvY9WbW1>:

 #include <print>

 int main(int const argc, char **const argv)
{
    auto func = [argv](this auto&& self, int count)
    {
    if ( 0 == count ) return;
    std::println("{}", argv[count - 1]);
    self(count - 1);
    };
    func(argc);
}

>
> Perhaps, in the case of nested lambdas, we could even specify a number
> to std::recurse to specify which function to re-enter. Looking at the
> above code snippet:
>
> std::recurse<0> = Re-enter the immediate function (might be a lambda)
> std::recurse<-1> = Re-enter the enclosing function (might be a lambda)
> std::recurse<-2> = Re-enter the enclosing enclosing function (and so
> on...)
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2025-05-15 13:17:01