std :: bind当作为右值引用传递时丢失引用 [英] std::bind lose reference when delivered as rvalue reference
问题描述
我有以下代码:
#include <stdio.h>
#include <functional>
template <typename T>
auto callback(T&& func) ->decltype(func())
{
return func();
}
double test(double& value)
{
value=value+1.0;
return value;
}
int main(void)
{
double t=1.0;
printf("%f\n",t);
test(t);
printf("%f\n",t);
callback(std::bind(test,t));
printf("%f\n",t);
}
并输出
1.000000
2.000000
2.000000
这意味着 callback
函数获得了 t
的副本,而不是 t
。我想知道发生了什么,因为 std :: bind
它应该是完美转发。
Which implies the callback
function got a copy of t
instead of a reference to t
. I am wondering what happened, since for std::bind
it should be perfect-forwarding.
推荐答案
std :: bind
默认使用值语义。这是一个正常的默认值,让你做如下安全的事情。
std::bind
uses value semantics by default. It's a sane default that lets you do things like the following safely.
int f(double x);
auto fun = std::bind(f, 1.0); // stores a copy, not a reference to a temporary
fun();
使用值语义是安全的:绑定参数的生命周期成为bind返回的对象的生命周期。使用参考语义不会有这样的保证。所以你需要是明确的,当你想要引用语义;如果你遇到麻烦,那么这是你的错。为了做到这一点,你需要使用 std :: ref
:
Using value semantics is safe: the lifetime of the bound arguments becomes the lifetime of the object returned by bind. Using reference semantics would not have that guarantee. So you are required to be explicit when you want reference semantics; if you get in trouble then it's your fault. In order to do that you need to use std::ref
:
int main(void)
{
double t=1.0;
printf("%f\n",t);
test(t);
printf("%f\n",t);
callback(std::bind(test, std::ref(t)));
printf("%f\n",t);
}
同样的协议在标准库中使用,如 std :: thread
构造函数。
This same protocol is used elsewhere in the standard library, like the std::thread
constructor.
这篇关于std :: bind当作为右值引用传递时丢失引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!