Size: a a a

2020 November 07

O

Ofee in pro.cxx
Aidar Fattakhov
Так у тебя ничего не referring наверное
Полагаю, в таком случае, всё что после but не относится к моему примеру, а значит, справедливым должно быть только начало предложения до запятой. Т.е. тело лямбды... yields(?) тело operator(). А поскольку внутри анонимной структуры (smallest block scope) мы можем вызвать operator() рекурсивно, полагаю, это должно быть справедливо и для лямбды? По крайней мере, я не вижу любого другого повода считать иначе
источник

AF

Aidar Fattakhov in pro.cxx
А this ты тоже можешь потрогать?
источник

AF

Aidar Fattakhov in pro.cxx
Мне кажется кто-то опять неправильно переложил компиляторы в стандарт добавив лишних ифов
источник

VS

Vlad Serebrennikov in pro.cxx
Ofee
На самом деле, написано:
The lambda-expression's compound-statement yields the function-body ([dcl.fct.def]) of the function call operator, but for purposes of name lookup, determining the type and value of this and transforming id-expressions referring to non-static class members into class member access expressions using (*this) ([class.mfct.non-static]), the compound-statement is considered in the context of the lambda-expression.

Но этот пункт вместе с примером вызывает ещё больше вопросов, да и относится, похоже, только к лямбде, объявленной внутри функции-члена другого класса

Что же касается лямбды без захвата — я ничего полезного не нашёл
так вроде ясно написано, что name lookup и прочие штуки выполняются в контексте, в котором лямбда объявлена. без оговорок на класс и наличие захвата
источник

x

xahise in pro.cxx
Привет
Такой, возможно, глупый вопрос, но как очищать память?

У меня есть struct, содержащий int и 2 указателя на struct

При попытке очистить память по указателям на эту структуру (delete ...) она либо не очищается из памяти, либо каким-то образом растёт в объемах 😅
источник

O

Ofee in pro.cxx
Vlad Serebrennikov
так вроде ясно написано, что name lookup и прочие штуки выполняются в контексте, в котором лямбда объявлена. без оговорок на класс и наличие захвата
Хм, кажется, такая трактовка имеет смысл, спасибо
источник

O

Ofee in pro.cxx
xahise
Привет
Такой, возможно, глупый вопрос, но как очищать память?

У меня есть struct, содержащий int и 2 указателя на struct

При попытке очистить память по указателям на эту структуру (delete ...) она либо не очищается из памяти, либо каким-то образом растёт в объемах 😅
источник

x

xahise in pro.cxx
Спасибо
источник

АК

Александр Караев... in pro.cxx
Ofee
Какая из имплементаций права? У всех трёх разное мнение касательно корректности этого кода. MSVC считает, что всё хорошо. GCC не позволяет из тела лямбды вызвать нешаблонный operator(), но позволяет вызвать шаблонный (очевидно, это следствие того, как реализован оператор каста к указателю на функцию). Clang же не позволяет вызвать ни тот, ни другой

>> The type of a lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type, called the closure type

>> The closure type for a lambda-expression has a public inline function call operator (for a non-generic lambda) or function call operator template (for a generic lambda)

>> An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing
— ...

(
http://eel.is/c++draft/expr.prim.lambda#closure-1 )

Ни в последнем процитированном пункте, ни во всём разделе, я не нашёл никаких исключений, касающихся name lookup для лямбд без захвата, т.е. поиск имён в лямбде должен соответствовать поиску имён внутри  unnamed non-union class type, а значит, можно предположить, что в следующем куске кода поведение при вызове f(3) и l(3) должно быть эквивалентно:

struct /* unnamed */ {
   template<typename Auto>
   constexpr int operator()(Auto n) const {
     if (n <= 1) return 1;
     else return n * operator()(n-1);    
   }
} f;

void foo() {
 constexpr auto l = [](auto n) -> int {
   if (n <= 1) return 1;
   else return n * operator()(n-1);
 };

 static_assert(l(3) == f(3));
};

При этом, кажется, при нешаблонном operator() и GCC, и MSVC оба могут быть правы, допускаю даже, что могут быть правы одновременно. Но я не вижу ни одного аргумента в пользу Clang, который не позволяет вызвать шаблонный operator() вообще


Быть может, у кого-то есть мысли на этот счёт?
Судя по тому, сколько грабель было сломано и пропозалов написано, рекурсивные лямбды невозможно реализовать средствами текущего стандарта. Обычно делают хелпер, который оборачивает любую лямбду, добавляя в неё первым аргументом auto self
источник

O

Ofee in pro.cxx
Собственно, чтобы они были возможны, достаточно явно разрешить обращение к operator(), как это позволяют MSVC и частично GCC, я до такой формы вызова дошёл совершенно случайно, решая совсем уж непрактичную задачу, и на удивление, я не смог где-либо найти информацию о том, баг это или фича, поэтому и пошёл искать в стандарте
источник

AF

Aidar Fattakhov in pro.cxx
Ofee
Собственно, чтобы они были возможны, достаточно явно разрешить обращение к operator(), как это позволяют MSVC и частично GCC, я до такой формы вызова дошёл совершенно случайно, решая совсем уж непрактичную задачу, и на удивление, я не смог где-либо найти информацию о том, баг это или фича, поэтому и пошёл искать в стандарте
Ещё один иф в стандарте?
источник

AF

Aidar Fattakhov in pro.cxx
Вопрос все ещё открыт, типа почему они вообще это позволяют
источник

LA

Liber Azerate in pro.cxx
Александр Караев
Судя по тому, сколько грабель было сломано и пропозалов написано, рекурсивные лямбды невозможно реализовать средствами текущего стандарта. Обычно делают хелпер, который оборачивает любую лямбду, добавляя в неё первым аргументом auto self
В каком смысле невозможно реализовать рекурсивную лямбду? Это довольно-таки несложно
источник

АК

Александр Караев... in pro.cxx
Liber Azerate
В каком смысле невозможно реализовать рекурсивную лямбду? Это довольно-таки несложно
Покажи, если несложно. Очевидно, что вариант с std::function, хелпер-функциями/классами не считается "чистым"
источник

AF

Aidar Fattakhov in pro.cxx
А захват считается оверхедным
источник

LA

Liber Azerate in pro.cxx
Александр Караев
Покажи, если несложно. Очевидно, что вариант с std::function, хелпер-функциями/классами не считается "чистым"
Ну если так, то, видимо, нельзя. Однако это какая-то непрактичная "чистота"
источник

LA

Liber Azerate in pro.cxx
Aidar Fattakhov
А захват считается оверхедным
По ссылке-то?
источник

AF

Aidar Fattakhov in pro.cxx
И по ссылке в тч
источник

AF

Aidar Fattakhov in pro.cxx
Непонятно как себя не по ссылке принять
источник

АК

Александр Караев... in pro.cxx
Liber Azerate
Ну если так, то, видимо, нельзя. Однако это какая-то непрактичная "чистота"
Почему непрактичная-то? Если мне нужна рекурсивная функция, то аналогично мне может быть нужна рекурсивная лямбда без каких-то доп. ограничений
источник