有人能解释为什么在通过“身份”函数foo1
后引用变得无效吗? A
的“地址”不是传入并由 foo1
返回吗?
struct A {
A(int x) : x_(x) {}
int x_;
};
int main() {
function<const A&(const A& r)> foo1 = [](const A& r) {
return r;
};
vector<A> vec{1, 2, 3};
cout << foo1(vec[0]).x_ << endl; // RUNTIME ERROR
return 0;
}
问题线有何不同:
const A& r = vec[0];
const A& r1 = r;
最佳答案
问题是你的 lambda。它没有做你认为它做的事:
function<const A&(const A& r)> foo1 = [](const A& r) {
// ~~~~~~
return r;
};
请注意,没有尾随返回类型。这意味着它是自动推断的。推导永远不会给你一个引用类型,所以这个 lambda 返回一个 A
,而不是一个 A const&
。然后将返回的临时 A
绑定(bind)到 function
的 operator()
的返回 A const&
。那个临时的不是终生延长的。但是当我们完成调用 foo1()
时,我们有一个对该临时 A
的悬空引用。这是未定义的行为,我猜你的编译器会给你一个有用的运行时错误。
要解决这个问题,您需要明确指定返回类型:
function<const A&(const A& r)> foo1 = [](const A& r) -> A const& {
return r;
};
但即使这样也很危险,因为您仍然可以将 temporary A
传递给此函数并获取悬空引用。没有真正的解决方法。
落入这个陷阱的难易程度也是LWG Issue 2813
关于c++ - 通过标识函数后,左值引用变得无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42162199/