gpt4 book ai didi

c++ - 为什么一个类需要移动操作来绑定(bind)到一个 std::function ,该函数具有该类按值传递的签名?

转载 作者:行者123 更新时间:2023-12-03 22:59:43 25 4
gpt4 key购买 nike

在以下代码中:

struct X
{
X() = default;
X(const X&) { printf("copy construct\n"); }
X& operator=(const X&) { printf("copy assign\n"); return *this; }
X(X&&) { printf("move construct\n"); }
X& operator=(X&&) { printf("move assign\n"); return *this; }
// Replacing the above two lines with these lines below causes a compile error.
// X(X&&) = delete;
// X& operator=(X&&) = delete;
};

void f(X x) {}

int main()
{
X x;
std::function<void (X)> fx(f);
f(x);

return 0;
}
如果我将 struct X 定义为具有复制和移动操作,则带有签名 void (X) 的 std::function 能够绑定(bind)到它。但是,如果我删除移动操作,代码将不再编译,并出现以下错误:
prog.cc:26:29: error: no matching constructor for initialization of 'std::function<void (X)>'
std::function<void (X)> fx(f);
candidate template ignored: requirement '__callable<void (*&)(X), false>::value' was not satisfied [with _Fp = void (*)(X)]
function(_Fp);
我只是想了解如果签名描述了 X 按值传递的函数,为什么需要移动操作?

最佳答案

std::function<void (X)> fx(f)构造函数调用格式错误。
首先,对这个构造函数的要求:

[func.wrap.func.con]
template<class F> function(F f);
7 Constraints: F is Lvalue-Callable (20.14.16.2) for argument types ArgTypes... and return type R.

[func.wrap.func]/2 A callable type (20.14.2) F is Lvalue-Callable for argument types ArgTypes and return type R if the expressionINVOKE<R>(declval<F&>(), declval<ArgTypes>()...), considered as an unevaluated operand (7.2), is well-formed (20.14.3).


我相信 f实际上对于参数类型不是 Lvalue-Callable X ,无论这听起来多么奇怪。这取决于 declval 的定义。 :

[declval]
template<class T> add_rvalue_reference_t<T> declval() noexcept;


所以, declval<X>() 的类型实际上是 X&& ,而不是 X .一个电话 f(declval<X>())需要从这个右值引用移动到按值参数 - 但移动构造函数被声明为删除。确实, sizeof(f(std::declval<X>()), 0); fails to compile ,还提示删除的移动构造函数。
换句话说, std::function<void (X)> fx(f)格式错误的原因与 X x; f(std::move(x)); 基本相同格式不正确。

实际上, std::function::operator()需要能够将其参数转发给包装的可调用对象,并使用 std::forward为此 - 这也会将右值转换为右值引用并期望能够移动参数。

关于c++ - 为什么一个类需要移动操作来绑定(bind)到一个 std::function ,该函数具有该类按值传递的签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66870825/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com