为什么我的 std::ref 无法按预期工作?

Why does my std::ref not work as expected?

提问人:User12547645 提问时间:2/23/2020 更新时间:2/23/2020 访问量:676

问:

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

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

为什么我有这样的期望?因为我路过.在包装器中,引用然后按值捕获。我本来会假设,因为我正在使用这个值,现在仍然是对 .我正在改变,并希望这反映出这种变化。tmpstd::refwrapperstd::reftmptmpf

在这里玩代码。

#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();
}
C++ 逐个引用 higher-order-functions 按值传递

评论

0赞 Fureeish 2/23/2020
"std::ref 给你一个对某物的左值引用“ - 。它给你一些东西。std::reference_wrapper

答:

1赞 NutCracker 2/23/2020 #1

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

  1. auto wrapper(int& i, F func) {...}
  2. void f(int& i) {...}

并且还通过引用进行 lambda 捕获。那你就不需要了.return [&]() { return func(i); };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) {...}

评论

0赞 User12547645 2/23/2020
好。。。但为什么不为我这样做呢?我认为它的要点之一是要引用某些东西,即使我传递了价值std::ref
0赞 NutCracker 2/23/2020
@User12547645因为您的函数不接受引用或 .他们接受副本。std::reference_wrapper<int>
2赞 super 2/23/2020 #2

这不起作用的原因是您的函数接受 as 参数。wrapperint

std::ref返回一个 . 当你把它传递给一个需要的函数时,你会得到一个隐式转换,你不再使用引用。std::reference_wrapperint

如果将函数签名更改为使用 a,它将给出预期的结果。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();
}

评论

0赞 User12547645 2/23/2020
现在这很有意义!我不知道 的隐式转换 .但是,是的,听起来合乎逻辑。谢谢!reference_wrapper<int>int