Я пытаюсь выяснить, как получить адрес лямбда-функции внутри себя. Вот пример кода:
[]() {
std::cout << "Address of this lambda function is => " << ????
}();
Я знаю, что могу перехватить лямбду в переменной и напечатать адрес, но я хочу сделать это на месте, когда эта анонимная функция выполняется.
Есть ли более простой способ сделать это?
this
.Ответы:
Это не возможно напрямую.
Однако лямбда-захваты являются классами, и адрес объекта совпадает с адресом его первого члена. Следовательно, если вы захватываете один объект по значению в качестве первого захвата, адрес первого захвата соответствует адресу лямбда-объекта:
Выходы:
Кроме того, вы можете создать лямбда- шаблон дизайна декоратора, который передает ссылку на лямбда-захват в свой оператор вызова:
источник
Невозможно напрямую получить адрес лямбда-объекта внутри лямбды.
Теперь, как это бывает, это довольно часто полезно. Наиболее распространенное использование для того, чтобы рекурсировать.
y_combinator
Приходит из языков , где вы никогда не могли говорить о себе , пока вы где определены. Это может быть реализовано довольно легко в C ++ :Теперь вы можете сделать это:
Варианты этого могут включать в себя:
где
self
переданный может быть вызван без передачи вself
качестве первого аргумента.Второе соответствует настоящему y комбинатору (он же комбинатор с фиксированной точкой), я считаю. То, что вы хотите, зависит от того, что вы подразумеваете под «адресом лямбды».
источник
F
это не стандартная схема, тоy_combinator
нет, поэтому вменяемые гарантии не предоставляются.Один из способов решить эту проблему - заменить лямбду классом рукописных функторов. Это также то, что лямбда по сути находится под капотом.
Затем вы можете получить адрес
this
, даже не назначая функтор переменной:Преимущество в том, что он на 100% портативен, и его очень легко обдумать и понять.
источник
struct { void operator()() { std::cout << "Address of this functor is => " << this << '\n'; } } f;
Захватите лямбду:
источник
std::function
здесь не нужна, и это требует значительных затрат. Кроме того, копирование / перемещение этого объекта сломает его.Это возможно, но сильно зависит от оптимизации платформы и компилятора.
На большинстве известных мне архитектур есть регистр, называемый указателем команд. Смысл этого решения состоит в том, чтобы извлечь его, когда мы находимся внутри функции.
На amd64 Следующий код должен дать вам адреса, близкие к функциональному.
Но, например, на gcc https://godbolt.org/z/dQXmHm с
-O3
функцией уровня оптимизации может быть встроено.источник
thread_local
длительным хранением. Здесь вы пытаетесь получить адрес возврата функции, а не объекта. Но даже это не сработает, потому что пролог сгенерированной компилятором функции помещает в стек и корректирует указатель стека, чтобы освободить место для локальных переменных.