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

Vic*_*tor 3 c++ lambda

考虑以下无法编译的代码:

#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

Ser*_*eyA 6

诊断是超级误导。虽然很明显互斥是不可复制的,但在提供的代码段中没有请求互斥的复制!

问题的直接原因是std::function<>模板化构造函数(std::function从 lambda 创建时将被调用的构造函数)在提供参数类型的对象上受到SFINAE限制Callable

Callable 不满意,因为调用表达式尝试按值传递互斥锁,并且互斥锁不可复制。

结果,编译器找不到任何合适的构造函数来构造std::function对象并观察到诊断问题。

似乎无法构造std::function类似的东西似乎有点不幸,因为您可以使用临时构造的对象调用普通函数或 lambda,例如

f(t{});
Run Code Online (Sandbox Code Playgroud)

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