为什么我不能将具有不可复制类参数的 lambda 转换为 std::function?



考虑以下编译失败的代码:

#include <mutex>
#include <functional>
class t{
std::mutex m;
};
std::function<void(t test)> func = [](t test) {return;};

生成以下错误:

错误:从'<lambda(t(>'到非标量类型'std::function<void(t(>'请求的

你能向我解释一下为什么这个转换不起作用吗?

附言:这里的示例:https://godbolt.org/z/7se8crf41

诊断非常具有误导性。虽然互斥体显然是不可复制的,但在提供的代码段中没有复制请求的互斥体!

问题的直接原因是std::function<>模板化构造函数(当从lambda创建std::function时会调用该构造函数(被SFINAE限制为对象Callable,并提供了参数类型。

Callable不满足,因为调用表达式试图按值传递互斥,而互斥是不可复制的。

因此,编译器找不到任何合适的构造函数来构造std::function对象,并出现了所观察到的诊断问题。

似乎无法构造这样的std::function也有点不幸,因为您可以使用这样的临时构造对象来调用正常函数或lambda

f(t{});

由于保证的副本省略。虽然对std::mutex这样做没有意义,但对其他不可复制、不可移动的类可能有意义。

最新更新