Объекты имеют жизни; функции нет. Функции не живут и не умирают; они всегда существуют. Таким образом, функция не может выходить «из области видимости», и функция, на которую указывает предыдущий действительный указатель функции, исчезает. Независимо от того, откуда они берутся, указатели на функции всегда действительны.
Теперь это игнорирует динамическую нагрузку и т. Д., Но это нестандартное поведение.
Указатель функции, который вы возвращаете из лямбда, является указателем на функцию. Это не особенное или волшебное. Поэтому он ведет себя не иначе, как любой другой указатель на функцию.
Возможно ли, что в результате преобразования к мочеиспусканию (*)() указывает на то, которое вызывает функцию-член, связанный с какой-либо объект?
Это гораздо более сложный вопрос. Тот, который стандарт кажется довольно недооцененным. В стандарте указывается только:
адрес функции, которая при вызове имеет тот же эффект, что и вызов оператора вызова типа замыкания.
Что означает «такой же эффект», это вопрос. Можно утверждать, что «тот же эффект» означает выполнение того, что сделал оператор вызова функции, выполняя ту же последовательность утверждений. Можно также утверждать, что «тот же эффект» означает вызов самого объекта замыкания.
Последний случай может показаться сложным для реализации, но помните, что магия компилятора может быть использована. Закрытие может возвращать указатель функции, специфичный для экземпляра, который назначается закрытием по запросу. Или некоторые-такие.
Ненормативный текст, по-видимому, не очень подходит по этому вопросу. Существует пример закрытия для (родовой) лямбды, в котором говорится следующее:
template<class T> auto operator()(T t) const { ... }
template<class T> static auto lambda_call_operator_invoker(T a) {
// forwards execution to operator()(a) and therefore has
// the same return type deduced
...
}
Комментарий в вопросе предполагает перенаправление, но это потребовало бы, что статический вызова построить новый экземпляр класса lambda, чтобы выполнить переадресацию.
В целом стандарт не дает понять, является ли обращение к сгенерированному указателю функции после уничтожения закрытия законным.
Интересный вопрос. Поскольку указатель укажет на некоторый элемент * static * "invoker", у статического члена нет другого выбора, кроме как использовать какой-то фиктивный объект для вызова 'operator()' лямбды (потому что последний нестационар). Этот фиктивный код должен быть либо локальным, либо «invoker», или статическим, то есть должен работать нормально в вышеупомянутом контексте. Но я не сразу вижу эту гарантию в спецификации языка. Спецификация языка даже не постулирует существование этого фиктивного объекта. – AnT
@ant Почему? Мне нужно запустить тот же код. Зачем это нужно в 'operator()'? 'operator()' можно было бы реализовать, вызвав статическую функцию, которая 'operator void (*)()()' возвращает – Yakk
. Я бы хотел, чтобы все «длинные» вопросы были такими короткими –