考虑以下无法编译的代码:
#include <mutex>
#include <functional>
class t{
std::mutex m;
};
std::function<void(t test)> func = [](t test) {return;};
Run Code Online (Sandbox Code Playgroud)
生成以下错误:
错误:请求从“<lambda(t)>”转换为非标量类型“std::function<void(t)>”
你能向我解释为什么这种转换不起作用吗?
PS:现场示例:https : //godbolt.org/z/7se8crf41
诊断是超级误导。虽然很明显互斥是不可复制的,但在提供的代码段中没有请求互斥的复制!
问题的直接原因是std::function<>模板化构造函数(std::function从 lambda 创建时将被调用的构造函数)在提供参数类型的对象上受到SFINAE限制Callable。
Callable 不满意,因为调用表达式尝试按值传递互斥锁,并且互斥锁不可复制。
结果,编译器找不到任何合适的构造函数来构造std::function对象并观察到诊断问题。
似乎无法构造std::function类似的东西似乎有点不幸,因为您可以使用临时构造的对象调用普通函数或 lambda,例如
f(t{});
Run Code Online (Sandbox Code Playgroud)
由于保证复制省略。虽然对 这样做没有意义std::mutex,但对于其他不可复制、不可移动的类可能是有意义的。