通过身份函数后,左值引用变为无效

时间:2017-02-10 14:48:24

标签: c++ c++11

有人会在通过“身份”功能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;

问题行与以下内容有何不同:

{{1}}

2 个答案:

答案 0 :(得分:43)

问题是你的lambda。它没有做你认为它做的事情:

function<const A&(const A& r)> foo1 = [](const A& r) { 
//                                               ~~~~~~
    return r;
};

请注意,没有尾随返回类型。这意味着它会自动推断出来。扣除从不为您提供引用类型,因此此lambda返回A,而不是A const&。返回的临时A然后绑定到A const& function的返回operator()。这暂时不是终生延长的。但是当我们完成调用foo1()时,我们对该临时A有一个悬空引用。这是未定义的行为,我猜你的编译器会给你一个有用的运行时错误。

要解决此问题,您需要明确指定返回类型:

function<const A&(const A& r)> foo1 = [](const A& r) -> A const& { 
    return r;
};

但即使这样也很危险,因为您仍然可以将临时 A传递给此函数并获取悬空引用。没有真正的方法围绕那一个。

陷入此陷阱的容易程度也是LWG Issue 2813

答案 1 :(得分:12)

当您的function对象返回const A&时,您提供的lambda不会。它的返回类型是从return语句推导出来的,返回语句推导为A。尝试添加这样的显式返回类型。

function<const A&(const A& r)> foo1 = [](const A& r) -> const A& { 
    return r;
};