为什么 C++ 标准中 std::function<>::operator() 的定义是:
R operator()(ArgTypes...) const;
而不是
R operator()(ArgTypes&&...) const;
?
有人会认为要正确转发参数,我们需要 && 然后使用 std::forward<ArgTypes>...
转接调用时在函数体中?
我部分重新实现了 std::function 来测试它,我发现如果我使用 &&,当我稍后尝试按值传递参数时,我会从 g++ 中得到“无法将 'xxx' 左值绑定(bind)到 'xxx&&'”运算符(operator)()。我认为我对右值/转发概念有足够的了解,但我仍然无法理解这一点。我错过了什么?
最佳答案
仅当函数本身(在本例中为 operator()
)被模板化并且模板参数被推导出时,完美转发才有效。对于 std::function
,您从 class 本身的模板参数中获取 operator()
参数类型,这意味着它们永远不会从任何论点推导出来。
完美转发背后的全部技巧是模板参数推导部分,与引用折叠一起,就是完美转发。
我只是方便地链接到 my other answer about std::forward
在这里,我解释了完美转发(和 std::forward
)的工作原理。
请注意,std::function
的 operator()
不需要完美转发,因为用户自己决定参数应该是什么。这也是你不能只将 &&
添加到 operator()
的原因;举个例子:
void foo(int){}
int main(){
// assume 'std::function' uses 'ArgTypes&&...' in 'operator()'
std::function<void(int)> f(foo);
// 'f's 'operator()' will be instantiated as
// 'void operator()(int&&)'
// which will only accept rvalues
int i = 5;
f(i); // error
f(5); // OK, '5' is an rvalue
}
关于C++11 std::function 和完美转发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11135354/