TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.36K subscribers
Post #1079 4.46K
Сколько раз можно разыменовать лямбду?
#опытным

Давайте для начала поговорим о том, сколько раз можно разыменовать указатель?

Зависит от того, какой указатель мы имеем ввиду.

Тип int* можно разыменовать всего один раз. Получившийся объект после разыменования будет lvalue int, для которого отсутствует перегрузка operator*:

int i = 5;
int * p = &i;
std::cout << **p << std::endl; // error: indirection requires pointer operand ('int' invalid)


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

int i = 5;
int * p = &i;
int ** p1 = &p;
std::cout << **p1 << std::endl; // OK
std::cout << ***p1 << std::endl; // Error


Сколько же раз можно разыменовывать лямбду?

Так стоп. Как в лямбде можно применять оператор?

Лямбда без захвата неявно кастится к указателю на функцию. А указатель можно разыменовывать.

Так сколько?

Бесконечно

#include <iostream>

int main() {
auto ret = *****************************************[]{ return 23; };
std::cout << ret() << std::endl;
}


Чисто технически мы конечно ограничены количеством атомов во вселенной или, что более реально, возможностями компилятора обрабатывать длиннющие тексты программ. Но формальных ограничений нет.

#ЧЗХ?

Давайте подумаем, что происходит при разыменовании лямбды. Она приводится к указателю на функцию, оператор применяется и результатом мы получаем lvalue функции(саму функцию, а не указатель). Тип этого выражения – int().

А функции у нас что любят делать? Правильно, неявно преобразовываться к указателю на саму себя.

Поэтому можем применить оператор еще разик.

А потом еще и еще. И еще, и еще, и еще, и еще... Ну вы поняли.

В любом случае ret по итогам того же неявного преобразования будет иметь тип указателя на фукнцию:

static_assert(std::is_same_v<decltype(ret), int(*)()>);


По тем же рассуждениям, кстати, любой указатель на функцию тоже можно бесконечно разыменовать.

Спасибо, @Ivaneo, за любезно предоставленный примерчик.

Be limited only by your imagination. Stay cool.

#cppcore
  • ❤ 29
  • 👍 16
  • 😁 11
  • 🔥 2
  • 🤯 1
More from @grokaemcpp
  1. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  2. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  3. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  4. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  5. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
  6. Sep 25, 2026​​std::spanstream #опытным Радостная весть для всех, кто пользуется iostreams! В C++23 доб…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →