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
常量基准的寿命。事实上,这在 gcc 和 clang 中编译得很好,并且根据 valgrind 运行没有泄漏。
但是,当我这样更改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]:
第二个上下文是当引用绑定到临时时。引用绑定到的临时或作为引用绑定到的子对象的完整对象的临时对象在引用的生存期内持续存在,但以下情况除外:[..]
...但你没有这样做:你绑定到调用成员函数的结果(例如 operator[]
) 在对象上,并且该结果不是向量的数据成员!
(值得注意的是,如果你有一个std::array
而不是一个std::vector
,那么代码†绝对没问题,因为数组数据存储在本地,所以元素是子对象。
因此,您对f()
原始结果的逻辑元素有一个悬而未决的引用,该元素早已超出范围。
† 对不起可怕的初始化器,但好吧,责怪C++。
- OpenGL - 在 NDC 中计算位置适用于着色器,但不适用于'regular'程序
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 如何修复我的最大公约数代码?它适用于除零和零以外的所有数字
- 选择排序C++(已修改)并非适用于所有情况
- 无法让"std::enable_if"适用于无作用域枚举
- 请找出我的代码中的错误,它在提交得到错误答案的同时仍然适用于我的所有测试用例
- 确定夏令时是否适用于特定日期
- 是否有一种 STL 算法可以最后找到,但它也适用于指针?
- QT 样式表主题,适用于使用属性选择器的整个应用程序
- C++带有适用于左值和右值的引用参数的函数
- 代码适用于调试,但不适用于发布
- C++17 和更新的 std::分配器是否适用于动态数量的自定义堆?
- 适用于大型数组的无复制线程安全环形缓冲区
- NRVO 是否也适用于协程?
- 约束包容是否仅适用于概念?
- 程序只适用于包含(无副作用)cout声明
- 适用于频繁更改的大型数据集的最佳数据结构
- 相同的 for 循环适用于其他项目,但不适用于此项目。为什么?
- 无法让 FastNoise 适用于草地
- 其中列 = 值,仅适用于整数值