Re: Не распарсил конструкцию с []
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 30.01.22 00:17
Оценка: +1 :))) :))
Здравствуйте, Shmj, Вы писали:

S>Кто может ткнуть носом, что значит [socket] — что за конструкция?


S>
S>socket.receive([socket](std::vector<unsigned char> data) {
S>  auto task = Async(process1, data);
S>  process(data);
S>  task.wait();

S>  socket.send(data, kNoCallback);
S>});
S>


Всегда хотел спросить, а тут такая возможность! А какие ищущения испытывает человек когда его из криокамеры выпускают?
Re[2]: Не распарсил конструкцию с []
От: Shmj Ниоткуда  
Дата: 30.01.22 00:52
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Всегда хотел спросить, а тут такая возможность! А какие ищущения испытывает человек когда его из криокамеры выпускают?


В C# такая концепция есть, по этому не вставило. Радость от того что в C++ пока не добавили деревья выражений — вот там действительно перелом сознания.
Re[2]: Не распарсил конструкцию с []
От: Shmj Ниоткуда  
Дата: 30.01.22 00:53
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Это анонимная функция (функция есть, а имени у нее нету), описанная прям по месту использования. В нонешнем C++ и не такое бывает.


А что еще бывает?
Re[6]: Не распарсил конструкцию с []
От: Evgeny.Panasyuk Россия  
Дата: 30.01.22 03:37
Оценка: +1
Здравствуйте, Marty, Вы писали:

M>>>Что значит — используемые?

AD>>Которые используются в теле лямбды.
M>Это уже оптимизация

Чтобы понять почему так, создай класс с говорящим деструктором, создай несколько объектов этого класса, вызови лямбду c [=] и посчитай вызовы деструкторов.
Re[3]: Не распарсил конструкцию с []
От: Evgeny.Panasyuk Россия  
Дата: 30.01.22 03:46
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Кстати ++03 ещё и не давал структуры с методами имплементировать внутри тела функции, требовал вытаскивать кишки наружу.



Это не так, такое работало даже в C++98. Были ограничения, да, например связанные с шаблонами, но конкретно описываемый пример работает.
Re[4]: Не распарсил конструкцию с []
От: Evgeny.Panasyuk Россия  
Дата: 30.01.22 03:53
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Ну я понимаю, что в сишном рантайме настоящую функцию на ходу не создашь. Но логически это именно функция.


В общем случае, даже чисто гипотетически-"логически" — это именно объект некоторого синтезированного класса, ибо есть состояние:
auto f = [i=int(1)]() mutable {
    cout << i++ << endl;
};
f();
auto fork = f;
f();
fork();


Pzz>Ну я понимаю, что в сишном рантайме настоящую функцию на ходу не создашь


Рантайм тут вообще ортогонален, ибо весь необходимый код генерируется статически, без всякой поддержки рантайма.
Re: Не распарсил конструкцию с []
От: Ip Man Китай  
Дата: 30.01.22 05:08
Оценка: +2
Непонятно, почему столько минусов и смеха. Вполне нормальный вопрос от человека, мало знакомого с C++11.

Или здесь собрались одни элитные C++ эксперты? Ну-ну.
Re[2]: Не распарсил конструкцию с []
От: Dair Россия https://dair.spb.ru
Дата: 30.01.22 07:11
Оценка: +2
Здравствуйте, Ip Man, Вы писали:

IM>Непонятно, почему столько минусов и смеха. Вполне нормальный вопрос от человека, мало знакомого с C++11.


Наверно, каждый из нас тоже в своё время задавал этот вопрос, когда впервые увидел подобную конструкцию. Над собой смеёмся.
Re[5]: Не распарсил конструкцию с []
От: Pzz Россия https://github.com/alexpevzner
Дата: 30.01.22 09:39
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

Pzz>>Ну я понимаю, что в сишном рантайме настоящую функцию на ходу не создашь


EP>Рантайм тут вообще ортогонален, ибо весь необходимый код генерируется статически, без всякой поддержки рантайма.


Ну вот в Go лямбда-выражения, со всякими там замыканиями и прочими делами, выдают абсолютно полноценный указатель на функцию. Ровно такой же, как если эту функцию (с совместимыми типами параметров, разумеется) статически описать и использовать ее имя в качестве значения.

Очевидно, что это связано с тем, на что именно там, под капотом, указывают указатели на функцию.

А в Си, где указатель на функцию является в буквальном смысле адресом перехода, замыканий и прочих неявных данных к нему не приделаешь. Это именно что ограничение рантайма. Рантайма не в смысле набора функций из стандартной библиотеки а в смысле среды, в которой исполняется пользовательский код.
Re[7]: Не распарсил конструкцию с []
От: Hobbes Россия  
Дата: 30.01.22 11:15
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Чтобы понять почему так, создай класс с говорящим деструктором, создай несколько объектов этого класса, вызови лямбду c [=] и посчитай вызовы деструкторов.


С одной стороны так-то оно так, а с другой стороны нельзя расчитывать на побочные эффекты создания и уничтожения объектов, и напороться на какой-нибудь copz elision.
Re[8]: Не распарсил конструкцию с []
От: Evgeny.Panasyuk Россия  
Дата: 30.01.22 11:37
Оценка:
Здравствуйте, Hobbes, Вы писали:

EP>>Чтобы понять почему так, создай класс с говорящим деструктором, создай несколько объектов этого класса, вызови лямбду c [=] и посчитай вызовы деструкторов.

H>С одной стороны так-то оно так, а с другой стороны нельзя расчитывать на побочные эффекты создания и уничтожения объектов, и напороться на какой-нибудь copz elision.

В первую очередь здесь дело не в побочных эффектах, а в том что именно произойдёт [=] в функции с десятком локальных переменных. И вот если бы всегда захватывалось всё — то приходилось бы всё время расписывать всё вручную, а так как захватывается только то что используется — то можно без проблем использовать [=].

H>а с другой стороны нельзя расчитывать на побочные эффекты создания и уничтожения объектов


Можно, здесь семантика вполне себе определенна. Естественно классы предоставляющие это должны иметь корректную copy/move semantic, и тогда никакой elision не помеха.
Re[6]: Не распарсил конструкцию с []
От: Evgeny.Panasyuk Россия  
Дата: 30.01.22 11:48
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>А в Си, где указатель на функцию является в буквальном смысле адресом перехода, замыканий и прочих неявных данных к нему не приделаешь. Это именно что ограничение рантайма. Рантайма не в смысле набора функций из стандартной библиотеки а в смысле среды, в которой исполняется пользовательский код.


При необходимости можно и на C++ конвертировать замыкания с состоянием в указатель на функцию. Если оставаться в рамках стандартна, то будут некоторые ограничения. Если же выйти немного за рамки стандарта, и ограничиться конечным набором целевых платформ, то можно и вовсе без ограничений.
Тем не менее, "логически" это всё равно не функция, а замыкание (или делегат) — ибо имеется вполне себе осязаемое состояние.
Re[7]: Не распарсил конструкцию с []
От: Pzz Россия https://github.com/alexpevzner
Дата: 30.01.22 11:53
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Тем не менее, "логически" это всё равно не функция, а замыкание (или делегат) — ибо имеется вполне себе осязаемое состояние.


Вот тебе совершенно классическая сишная функция с состоянием:

int NextI (void)
{
    static int i;
    return i++;
}


Присутствие состояния это не то, что отличает функцию от не-функции.
Re[8]: Не распарсил конструкцию с []
От: Evgeny.Panasyuk Россия  
Дата: 30.01.22 11:59
Оценка:
Здравствуйте, Pzz, Вы писали:

EP>>Тем не менее, "логически" это всё равно не функция, а замыкание (или делегат) — ибо имеется вполне себе осязаемое состояние.

Pzz>Вот тебе совершенно классическая сишная функция с состоянием:
Pzz> static int i;

Это глобальное состояние, пусть и с ограниченной областью видимости, а у замыкания состояние локально для конкретного объекта. Я выше не просто так привел пример с копированием состояния "fork"
Re[7]: Не распарсил конструкцию с []
От: night beast СССР  
Дата: 30.01.22 12:20
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

Pzz>>А в Си, где указатель на функцию является в буквальном смысле адресом перехода, замыканий и прочих неявных данных к нему не приделаешь. Это именно что ограничение рантайма. Рантайма не в смысле набора функций из стандартной библиотеки а в смысле среды, в которой исполняется пользовательский код.


EP>При необходимости можно и на C++ конвертировать замыкания с состоянием в указатель на функцию. Если оставаться в рамках стандартна, то будут некоторые ограничения.


как?
можно пример?
Re[8]: Не распарсил конструкцию с []
От: Evgeny.Panasyuk Россия  
Дата: 30.01.22 13:01
Оценка:
Здравствуйте, night beast, Вы писали:

EP>>При необходимости можно и на C++ конвертировать замыкания с состоянием в указатель на функцию. Если оставаться в рамках стандартна, то будут некоторые ограничения.

NB>как?
NB>можно пример?

Например. Если оставаться в рамках стандарта, то чтобы получить тысячу уникальных адресов функций, надо пред-определить тысячу функций на этапе компиляции. Что каждая из этих тысячи функций будет делать — может вполне себе зависеть от runtime состояния, как в примере.
Ограничение здесь это максимальное число одновременно живущих адресов функций — вполне терпимо учитывая что лимит контролируем и этот трюк нужен разве что для какого-то кривого C API который не удосужился в довесок к указателю на функцию взять хотя бы void* data.

Если выйти за рамки стандарта, то можно просто генерировать trampoline код налету (не забыв про DEP).
Re[9]: Не распарсил конструкцию с []
От: night beast СССР  
Дата: 30.01.22 13:07
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Например. Если оставаться в рамках стандарта, то чтобы получить тысячу уникальных адресов функций, надо пред-определить тысячу функций на этапе компиляции. Что каждая из этих тысячи функций будет делать — может вполне себе зависеть от runtime состояния, как в примере.


не, ну так не интересно.
я думал что-то более нормальное есть...
Re[6]: Не распарсил конструкцию с []
От: AlexGin Беларусь  
Дата: 30.01.22 15:23
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>[&, i] — допустимо. Общий захват — по ссылке, i — по значению.

АТ>[&, &i] — ошибка. Нельзя захватывать i по ссылке, если общий захват и так по ссылке.
АТ>[=, i] — ошибка. Нельзя захватывать i по значению, если общий захват и так по значению.
АТ>[=, &i] — допустимо. Общий захват — по значению, i — по ссылке.

АТ>http://eel.is/c++draft/expr.prim.lambda#capture-2

АТ>http://coliru.stacked-crooked.com/a/9fd6075650e3b6b8

Мне хорошо запомнилась статья на "хабре", которую использую уже несколько лет, в качестве руководства:
https://habr.com/ru/post/66021
Re[7]: Не распарсил конструкцию с []
От: Андрей Тарасевич Беларусь  
Дата: 30.01.22 17:36
Оценка: 2 (1) +1
Здравствуйте, AlexGin, Вы писали:

AG>Здравствуйте, Андрей Тарасевич, Вы писали:


АТ>>[&, i] — допустимо. Общий захват — по ссылке, i — по значению.

АТ>>[&, &i] — ошибка. Нельзя захватывать i по ссылке, если общий захват и так по ссылке.
АТ>>[=, i] — ошибка. Нельзя захватывать i по значению, если общий захват и так по значению.
АТ>>[=, &i] — допустимо. Общий захват — по значению, i — по ссылке.

АТ>>http://eel.is/c++draft/expr.prim.lambda#capture-2

АТ>>http://coliru.stacked-crooked.com/a/9fd6075650e3b6b8

AG>Мне хорошо запомнилась статья на "хабре", которую использую уже несколько лет, в качестве руководства:

AG>https://habr.com/ru/post/66021

Статья по ссылке содержит ту же ошибку:

[&, x, &y]              // захват всех переменных по ссылке, кроме x…


Нет, так в С++ не разрешается.

Возможно дело в том, что статься писалась в 2009, то есть до выхода финальной версии стандарта и в черновике подобное еще допускалось. Как я сказал выше, это выглядит как вполне логичная возможность. Меня удивляет, что ее запретили. Интересно было бы узнать, почему.

---

Порылся в черновиках: нет, даже самые ранние версии черновика С++11, в которых уже появилось описание лямбда-выражений (N2588, 2008 год), сразу запрещали такую избыточность в захватах. То есть статья на хабре по-видимому писалась очередным "практиком" и любителем "де факто", изучавшим С++ по разудалому творчеству GNU-шных студентов: GCC по умолчанию рапортует эту ошибку через "warning".

Опять же, мне это ограничение кажется странным (как, видать, и "GNU-шным студентам").
Best regards,
Андрей Тарасевич
Отредактировано 30.01.2022 20:26 Андрей Тарасевич . Предыдущая версия . Еще …
Отредактировано 30.01.2022 18:20 Андрей Тарасевич . Предыдущая версия .
Re[3]: Не распарсил конструкцию с []
От: Mystic Artifact  
Дата: 30.01.22 23:49
Оценка: 3 (1) +1
Здравствуйте, Shmj, Вы писали:


H>>Аргумент делегата

S>Делегата? А что в C++ их добавили? Или имеешь в виду ссылка на функцию?
Ещё в прошлом тысячелетии. Только в C# делегат это какая-то суперсущность которая по итогу все равно костыль. Делегатом в нормальном коде является любая сущность которой делегирут работу. Как правило это просто интерфейс (которые в C++ разумеется тоже добавили... в прошлом тысячелетии). Разница между хэндлером и делегатом — как правило исключительно в уме автора. Иногда — существуют и хэндлеры и делегаты одновременно реализуя один и тот же интерфейс. Опять же — разница умозрительная. {Ломает мозг? Ну, так, это потому, что некоторые вещи в C# названы в чудовищном отрыве от реальности без како1-либо неоходимости. Событие? Событие, извините, это не конструкция языка.}

Ну а про аргумент делегата — это и вовсе какая-то невесёлая шутка. Где там аргумент я не увидел, и как бы я мог... У функции — параметры! Аргументы — это значения параметров. Это очень просто на самом деле. Как только перестанете путать парамеры с аргументами в своей голове — я гарантирую: начнете плеваться и зубоскалить на половину хороших библиотек в докуменации которых это упорно путают. И тем не менее: консольная программа декларирует параметры командной строки (часто это мини язык) — но парсит она аргументы.

Всегда пожалуйста, Ваш КО.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.