我最近尝试做这样的事情:
auto x = std::make_unique<int>(1);
auto l = [y = std::move(x)]() { return *y; };
std::function<void()> f(std::move(l)); //error, requires copy construction
令我非常失望和困惑的是,它向我抛出了一堆错误消息。如您所知,
std::function
不允许从不可复制构造的类型进行构造。有什么具体原因吗?还是标准中的一个疏忽?仅移动类型的构造会带来什么问题?
std::function
could 采用仅移动可调用,但只能将自身限制为始终仅移动。它使用类型擦除来存储对象,因此它的静态行为必须代表它所存储的对象所需的最低公分母功能。
但事情是这样的:C++ 及其标准库中有很多地方期望可调用对象是可复制的。我所说的“很多”是指整个标准算法库。即使是 C++20 概念 indirect_unary_predicate
也需要 copy_constructible
value来获取这些函数。 仅移动
std::function
类型永远不能与任何此类算法一起使用。而仅移动是 std::function
采取仅移动类型的唯一方法。
std::function
可复制。
C++23 引入了
std::move_only_function
。 这种类型是可移动的,因为它期望其目标是可移动的。 它是不可复制的,因此它的目标不需要是可复制的。
auto x = std::make_unique<int>(1);
auto l = [y = std::move(x)]() { return *y; };
std::move_only_function<void()> f(std::move(l)); // no error