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

标签 c++ lambda

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

#include <mutex>
#include <functional>

class t{
    std::mutex m;
};

std::function<void(t test)> func = [](t test) {return;};

生成以下错误:

error: conversion from '<lambda(t)>' to non-scalar type 'std::function<void(t)>' requested

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

PS:这里是活生生的例子:https://godbolt.org/z/7se8crf41

最佳答案

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

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

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

因此,编译器无法找到任何合适的构造函数来构造 std::function诊断观察到的对象和问题。

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

f(t{});

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

关于c++ - 为什么我不能将具有不可复制类参数的 lambda 转换为 std::function?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68379058/

相关文章:

c++ - iwlib.h : No such file or directory

c++ - 如何在 Eigen 中近似比较 vector ?

java - 如何将 Java 双冒号运算符 (::) 翻译成 Scala?

c++11 信号系统

lambda - 计划中的 lambda 有什么意义?

c++ - Short int - 如何保存到文件

C++ 模拟 Pascal 中的记录数组

asp.net - 获取特定时期内我的所有帖子(lambda 表达式)

c# - 如何使用 Lambda 和 EF 返回列表而不是对象

c++ - Boost.Asio async_handshake 无法取消