为啥我的 std::ref 不能按预期工作?

Posted

技术标签:

【中文标题】为啥我的 std::ref 不能按预期工作?【英文标题】:Why does my std::ref not work as expected?为什么我的 std::ref 不能按预期工作? 【发布时间】:2020-06-07 07:08:29 【问题描述】:

std::ref 给你一个lvalue-reference 的东西。此引用被包装到一个对象中,然后您可以通过引用或值传递该对象。

下面代码的预期行为是它打印i is 2,但它打印i is 1为什么会这样?

我为什么会有这种期望?因为我通过std::reftmp 传递给wrapper。然后在包装器中按值捕获引用。我会假设,因为我使用的是std::ref,所以这个值现在仍然是对tmp 的引用。我正在更改 tmp 并希望 f 反映该更改。

Play with the code here.

#include <iostream>
#include <functional>

template<typename F>
auto wrapper(int i, F func) 
    return [=]()  return func(i); ;


void f(int i) 
    std::cout << "i is " << i << '\n';


int main() 
    int tmp = 1;
    auto func = wrapper(std::ref(tmp), f);
    tmp = 2;
    func();

【问题讨论】:

"std::ref 给你一个lvalue-reference 的东西" - 没有。它会给你std::reference_wrapper 的东西。 【参考方案1】:

您需要更改函数签名以接受引用:

    auto wrapper(int&amp; i, F func) ... void f(int&amp; i) ...

并且还通过引用 return [&amp;]() return func(i); ; 进行 lambda 捕获。那你就不需要std::ref了。

完整代码如下:

#include <iostream>
#include <functional>

template<typename F>
auto wrapper(int& i, F func) 
    return [&]()  return func(i); ;


void f(int& i) 
    std::cout << "i is " << i << '\n';


int main() 
    int tmp = 1;
    auto func = wrapper(tmp, f);
    tmp = 2;
    func();

现在上面的代码会打印出来:

i is 2

如果您仍想使用std::ref,那么您的模板函数应具有以下签名:

template<typename F>
auto wrapper(std::reference_wrapper<int> i, F func) ...

【讨论】:

好吧...但是为什么std::ref 不为我做呢?我认为其中一个要点是引用某些东西,即使我是按值传递 @User12547645 因为您的函数不接受引用或std::reference_wrapper&lt;int&gt;。他们接受副本。【参考方案2】:

这不起作用的原因是因为您的 wrapper 函数将 int 作为参数。

std::ref 返回一个std::reference_wrapper。 当您将其传递给需要 int 的函数时 您将获得隐式转换,并且不再使用引用。

如果您将函数签名更改为使用std::reference_wrapper,它将给出预期的结果。

#include <iostream>
#include <functional>

template<typename F>
auto wrapper(std::reference_wrapper<int> i, F func) 
    return [=]()  return func(i); ;


void f(int i) 
    std::cout << "i is " << i << '\n';


int main() 
    int tmp = 1;
    auto func = wrapper(std::ref(tmp), f);
    tmp = 2;
    func();

【讨论】:

现在这很有意义!我不知道reference_wrapper&lt;int&gt;int 的隐式转换。但是,是的,听起来合乎逻辑。谢谢!

以上是关于为啥我的 std::ref 不能按预期工作?的主要内容,如果未能解决你的问题,请参考以下文章

为啥字符串相等在此 Python 代码中不能按预期工作? [复制]

为啥 nodejs 中的睡眠不能按预期工作

为啥我的替换没有按预期工作[重复]

为啥我的依赖属性绑定没有按预期工作?

为啥我的查询没有按预期工作?

为啥我的 javascript 代码没有按预期工作