C++:在自己内部摧毁lambda

use*_*538 9 c++ lambda c++11

#include <iostream>
#include <functional>

int global = 9;
std::function<void()> functor;

int main()
{
    int* ptr = &global;
    functor = [ptr]
    {
        functor = nullptr;
        std::cout << *ptr << std::endl;
    };

    functor();
}
Run Code Online (Sandbox Code Playgroud)

这是ptr由lambda捕获的变量,并且在functor()调用functor中首先删除functor = nullptr然后访问ptr.我认为它ptr已被破坏,因为它是一个删除的仿函数的字段.所有编译器成功执行该程序而没有崩溃并打印"9",但我仍然怀疑这不是未定义的行为.有人可以证实吗?

Hol*_*Cat 8

确实未定义.

以下是您可以确认的方法:

#include <iostream>
#include <functional>

struct S
{
    ~S() {std::cout << "~S()\n";}
};

std::function<void()> functor;

int main()
{
    functor = [s = S()]
    {
        functor = nullptr;
        std::cout << "End of lambda\n";
    };

    functor();
}
Run Code Online (Sandbox Code Playgroud)

上面的代码打印(在GCC和Clang上):

~S()
~S()
~S()
End of lambda
Run Code Online (Sandbox Code Playgroud)

3个被破坏的实例是:一个被原始lambda捕获,一个被存储的副本functor捕获,一个被临时捕获,std::function::operator=(F &&)由于某种原因必须制作.