cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

Добавит возможности вызвать лямбду рекурсивно сам себя #464

Closed raidenluikang closed 2 years ago

raidenluikang commented 3 years ago

Сейчас лямбду нельзя вызвать сам себя. Для этого иногда придумывает разные хитрости, который не очень то элегантный. Например

std::function< int (int ) > factorial = [&] (int n) -> int
{
     if (n < 2) return 1;
     else return factorial(n-1) * n;
};

// usage
  factorial(10);

либо, такой


   auto factorial = [](auto self,  int n) -> int
{
      if (n < 2) return 1;
     else return self( self, n - 1) * n ;
};

// usage:
 factorial(  factorial,  10);

Может быть есть ещё другие приёмы, но все они не так элегантно и просто, как вызвать рекурсивной функцией, либо есть накладной расходы как std::function.

Два типа решение могу предлагать:

  1. Добавить ключегого слово self или this_ptr тому подобное внутри лямбда.
  2. Захватить название лямбда по умолчание.
oficsu commented 2 years ago

Есть более универсальное предложение, в том числе решающее и эту задачу. Крайне вероятно, что оно попадёт уже в ближайшие стандарты. Отличие от предложенного вами синтаксиса будет минимальным — в ключевом слове this перед auto self, что позволит переиспользовать существующее слово this вместо того, чтобы занимать self и принуждать пользователя использовать лишь его, а также в отсутствии необходимости явно передавать self внутрь вызова self:

auto factorial = [](this auto self,  int n) -> int
{
     if (n < 2) return 1;
     else return self(s̶e̶l̶f̶, n - 1) * n ;
};
apolukhin commented 2 years ago

Приняли в C++23 https://wg21.link/p0847