提问人:User12547645 提问时间:2/23/2020 更新时间:2/23/2020 访问量:676
为什么我的 std::ref 无法按预期工作?
Why does my std::ref not work as expected?
问:
std::ref
给你一个东西。此引用被包装到一个对象中,然后您可以按引用或按值传递该对象。lvalue-reference
下面代码的预期行为是打印 ,但它打印 。为什么?i is 2
i is 1
为什么我有这样的期望?因为我路过.在包装器中,引用然后按值捕获。我本来会假设,因为我正在使用这个值,现在仍然是对 .我正在改变,并希望这反映出这种变化。tmp
std::ref
wrapper
std::ref
tmp
tmp
f
#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();
}
答:
1赞
NutCracker
2/23/2020
#1
您需要更改函数签名以接受引用:
auto wrapper(int& i, F func) {...}
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 参数。wrapper
int
std::ref
返回一个 .
当你把它传递给一个需要的函数时,你会得到一个隐式转换,你不再使用引用。std::reference_wrapper
int
如果将函数签名更改为使用 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
评论
std::ref
给你一个对某物的左值引用
“ - 不。它给你一些东西。std::reference_wrapper