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++。
根据 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++。