C++ Embedded

@channel_cppembedded
recursive lambdas Дед проснулся от необычного шума. Странные звуки шли со двора. Кажется, там умирала в муках крупная свинья, а может сам Вельзевул созывал свое нечистое воинство. Осенив себя крестным знамением, старый атеист кинулся из избы, дабы зафиксировать факт начала апокалипсиса. Во дворе же вместо четырех всадников стояли Мишган и видавший виды запорожец красного цвета. Транспортное средство неистово извергало из себя звуковые колебания, а юноша самозабвенно тряс головой в такт. - Что это за музыка? - дед попытался перекричать адские рулады. - Что?! - отвлекся Мишган, - а, это "Поющие коммунальщики", дичайше звонкие ребята! - Откуда они в моем запорожце? Ты штатный приемник поставил? Неужели в эфире такую похабель передают?! Дед приготовился хвататься за сердце. - Не-е-ет! - довольно протянул Мишган, - лучше! Я туда "Романтик" запихал между сиденьями, из багажника твой хлам выкинул, колонки туда пристроил. - То-то, смотрю, фары у него круглее обычного... Не договорив последней фразы, старик закатил глаза и рухнул без чувств. Надеюсь, вас не постигла та же участь при просмотре нелепых попыток исполнить рекурсивный вызов лямбды. Ведь очень сложно что-то сделать правильно, если это не предусмотрено конструкцией. Схема хоть и работает, но выглядит экстремально странно. На эту аномалию указал в 2017 году некий мистер Richard Smith. В октябре в свет вышло предложение P0839R0 Recursive lambdas. Причины понятны, а в качестве решения предлагалось ввести явное имя лямбды, которое будет видно изнутри. 𝚊𝚞𝚝𝚘 𝚟𝚒𝚜𝚒𝚝_𝚝𝚛𝚎𝚎 = [&] 𝚟𝚒𝚜𝚒𝚝(𝚃𝚛𝚎𝚎 *𝚗𝚘𝚍𝚎) -> 𝚟𝚘𝚒𝚍 { // параметр 𝚟𝚒𝚜𝚒𝚝 именует объект лямбды 𝚒𝚏 (𝚗𝚘𝚍𝚎->𝚕𝚎𝚏𝚝) 𝚟𝚒𝚜𝚒𝚝(𝚗𝚘𝚍𝚎->𝚕𝚎𝚏𝚝); // и может быть использован для рекурсивных вызовов 𝚘𝚞𝚝 << 𝚗𝚘𝚍𝚎->𝚟𝚊𝚕𝚞𝚎; 𝚒𝚏 (𝚗𝚘𝚍𝚎->𝚛𝚒𝚐𝚑𝚝) 𝚟𝚒𝚜𝚒𝚝(𝚗𝚘𝚍𝚎->𝚛𝚒𝚐𝚑𝚝); }; // имя 𝚟𝚒𝚜𝚒𝚝 не видно здесь Предполагалось, что имя лямбды может быть использовано как ссылка на саму себя для любых целей, включая создание копий или захвата вложенным замыканием. Очень похоже на именованный this, вынесенный за скобки. Не нужно пугаться, комитет посчитал избыточным создавать особый синтаксис, применимый в общем-то только для лямбд и решающий только одну задачу рекурсивного вызова. Кажется, что возни получилось бы много, и еще не известно, в каком месте это стрельнет, какими багами на уровне стандарта. Тем более, что обороты набирала челобитная p0847R0, от могучей кучки авторов: Gašper Ažman, Simon Brand, Ben Deane и Barry Revzin. Это знаменитая в узких кругах Deducing this, опубликованная в далеком феврале 2018. "В этой фиче меня радует больше всего, - пишет Барри, - что в итоге получилась довольно простая структура, которая, тем не менее, решает множество совершенно независимых проблем. Действительно, многие из известных вариантов использования не были заложены изначально, а неожиданно открылись в процессе работы. Рекурсивные лямбда-выражения? Нате. Более эффективный подход к CRTP и интерфейсам построителей? Нате. Кто знает, сколько ещё интересных вещей придумают люди".В предложении есть пункт про рекурсивные лямбды. 3.2. Рекурсивные лямбды Раз уж мы открываем возможность позволить лямбдам отсылаться к себе, то вот нормальное альтернативное решение. Действительно, предложение deducing this позволяет явно передавать в метод ссылку на свой объект, почему это не сделать для лямбды? Концептуально правильно дать возможность лямбде отрефлексировать себя, как это было бы в обычном operator(). 𝚊𝚞𝚝𝚘 𝚏𝚒𝚋 = [](𝚊𝚞𝚝𝚘& 𝚝𝚑𝚒𝚜 𝚜𝚎𝚕𝚏, 𝚒𝚗𝚝 𝚗) { 𝚒𝚏 (𝚗 < 𝟸) 𝚛𝚎𝚝𝚞𝚛𝚗 𝚗; 𝚛𝚎𝚝𝚞𝚛𝚗 𝚜𝚎𝚕𝚏(𝚗-𝟷) + 𝚜𝚎𝚕𝚏(𝚗-𝟸); }; В первом предложении немного другой порядок объявления self, компилятор сейчас такой не поймет, нужно указать: this auto &self. Насколько прекрасным оказалось предложение p0847R0, что о прежней неуклюжей попытке все забыли. Логично, ведь явная передача this обеспечивает все то же самое, только с нормальным синтаксисом и понятными правилами.
Если у вас установлено приложение,
вы можете сразу перейти в канал