考虑以下代码:
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
std::thread t;
{
auto my_lambda = []{
int idx = 0;
while (true) {
std::this_thread::sleep_for (std::chrono::seconds(1));
std::cout << idx ++ << std::endl;
}
};
t = std::thread(my_lambda);
}
t.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
线程运行超出范围的 lambda 函数是否安全?
我看到 的构造函数std::thread
采用输入函数的通用引用Function&& f
,并且 lambda 被转换为结构。因此,如果结构体的实例在作用域内实例化,则线程将运行operator()
悬空引用。
{
struct lambda_translated { void operator()(){ ... } };
lambda_translated instance;
t = std::thread(instance);
}
Run Code Online (Sandbox Code Playgroud)
但我不确定我的推理是否正确。
附带问题:如果我在构造函数内将 lambda 声明为 R 值,行为是否会改变std::thread
:
#include …
Run Code Online (Sandbox Code Playgroud) 运行用 clang 编译的这段小代码片段时,我发现了一个奇怪的行为:
#include <iostream>
#include <exception>
#include <typeinfo>
struct Foo : public std::exception {
std::string myString;
Foo(const std::string& str) : myString(str) {}
Foo() : Foo(typeid(*this).name()) {}
};
int main()
{
Foo f;
std::cout << f.myString;
}
Run Code Online (Sandbox Code Playgroud)
typeid(*this).name()
委托构造函数内部调用的指令返回nullptr
导致分段错误的 a。在委托构造函数调用期间,std::exception
基类尚未初始化,这似乎是此行为的原因。
我想知道这段代码是否由于某种原因格式不正确,或者这种行为是预期的。
我无法使用 g++ 重现此错误,其中代码运行良好。
仅当基类是 std::exception 时才会发生这种情况,在任何其他情况下,即使在 clang 上也能正常工作。