std :: bind当作为右值引用传递时丢失引用 [英] std::bind lose reference when delivered as rvalue reference

查看:283
本文介绍了std :: bind当作为右值引用传递时丢失引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆