C++ - "Most important const" 不适用于表达式?

C++ - "Most important const" doesn't work with expressions?

根据 Herb Sutter 的文章 http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/,以下代码是正确的:

#include <iostream>
#include <vector>
using namespace std;

vector<vector<int>> f() { return {{1},{2},{3},{4},{5}}; }

int main()
{
    const auto& v = f();
    cout << v[3][0] << endl;
}

v 的生命周期延长到 v const 引用的生命周期。 事实上,根据 valgrind,这可以很好地使用 gcc 和 clang 进行编译,并且可以无泄漏地运行。

但是,当我这样更改 main 函数时:

int main()
{
    const auto& v = f()[3];
    cout << v[0] << endl;
}

它仍然可以编译,但 valgrind 警告我在函数的第二行中读取无效,因为第一行内存已释放。

这是符合标准的行为还是 g++ (4.7.2) 和 clang (3.5.0-1~exp1) 中的错误?

如果它符合标准,我觉得很奇怪......哦好吧。

这里没有错误,除了你的代码。

第一个示例有效,因为当您将 f() 的结果绑定到 v 时,您延长了该结果的生命周期。

在第二个示例中,您没有将 f() 的结果绑定到任何东西,因此它的生命周期 延长。绑定到它的子对象将计数:

[C++11: 12.2/5]: The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except: [..]

…但你没有这样做:你绑定到对象上调用成员函数(例如 operator[])的结果,而该结果不是向量的数据成员!

(值得注意的是,如果你有一个 std::array 而不是 std::vector,那么 the code 绝对可以作为数组数据存储在本地,所以元素是子对象。)

因此,您有一个对 f() 的原始结果的逻辑元素的悬空引用,它早已超出范围。

对可怕的初始值设定项感到抱歉,但是,好吧,归咎于 C++。