考虑以下编译失败的代码:
#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
这样做没有意义,但对其他不可复制、不可移动的类可能有意义。