You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建std::reference_wrapper的引用超出作用域后,其行为及代码疑问

问题

当用于创建std::reference_wrapper的引用超出作用域时,会发生什么?若底层对象仍然存在,该wrapper是否仍能访问该对象?还是会变为悬空引用,使用它会导致未定义行为(UB)?


实验代码

#include <iostream>
using namespace std;

struct mytype {
    int stuff;
};

mytype m;

bool myfunc(mytype& my) { return my.stuff > 0; }

void fill(std::reference_wrapper<mytype>& rwrap) {
    std::cout << "entering fill" << std::endl;
    std::cout << "myfunc(rwrap) : " << myfunc(rwrap) << std::endl;
    rwrap = std::ref(m);
    std::cout << "myfunc(rwrap): " << myfunc(rwrap) << std::endl;
    std::cout << "fill done" << std::endl;
}

int main() {
    mytype a;
    a.stuff = 7;
    std::reference_wrapper<mytype> r = a;

    std::cout << "a.stuff: " << a.stuff << std::endl;
    std::cout << "r.stuff(pre):  " << r.get().stuff << std::endl;
    std::cout << "myfunc(r):" << myfunc(r) << std::endl;

    fill(r);

    std::cout << "r.stuff(post): " << r.get().stuff << std::endl;
    std::cout << "myfunc 4: " << myfunc(r) << std::endl;

    std::cout << "a.stuff: " << a.stuff << std::endl;
}

输出结果

a.stuff: 7
r.stuff(pre):  7
myfunc(r):1
entering fill
myfunc(rwrap) : 1
myfunc(rwrap): 0
fill done
r.stuff(post): 0
myfunc 4: 0
a.stuff: 7

修改后的测试代码

void fill(std::reference_wrapper<mytype>& rwrap) {
    mytype& mref1 = m;
    mytype& mref2 = mref1;
    mytype& mref3 = mref2;
    mytype& mref4 = mref3;
    std::cout << "entering fill" << std::endl;
    std::cout << "myfunc(rwrap) : " << myfunc(rwrap) << std::endl;
    rwrap = std::ref(mref4);
    std::cout << "myfunc(rwrap): " << myfunc(rwrap) << std::endl;
    std::cout << "fill done" << std::endl;
}

结论与解释

std::reference_wrapper本质是对普通引用的封装,行为和普通引用完全一致:

  • 当用于创建wrapper的中间引用超出作用域时,只要底层对象仍存活,wrapper不会变成悬空引用。因为wrapper绑定的是底层对象本身,而非那个中间引用。比如修改后的代码里,mref1到mref4都是全局对象m的引用,即使这些中间引用在fill函数结束后销毁,wrapper绑定的依然是m,所以可以正常访问。
  • 只有当wrapper绑定的底层对象被销毁时,它才会变为悬空引用,此时访问会触发未定义行为。

你的实验代码运行正常是预期行为:

  • 初始r绑定的a在main全程存活;
  • 后续rwrap = std::ref(m)将r重新绑定到全局对象m,m的生命周期覆盖整个程序,所以所有访问都是合法的,并非侥幸。

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 05:38:00