c++ - C++ constexpr 构造函数初始化垃圾值
问题描述
我想要一个简单的类,它可以封装一个指针和一个大小,就像 C++20 那样std::span
,我想。我正在使用 C++(准确地说是 g++ 11.2.1)
我想要它,这样我就可以拥有一些恒定的模块级数据数组,而不必计算每个数组的大小。
但是,我的实现仅在某些时候“有效”,这取决于优化标志和编译器(我在 Godbolt 上尝试过)。因此,我犯了一个错误。我该如何正确地做到这一点?
这是实现加上一个测试程序,它打印出元素的数量(总是正确的)和元素(通常是错误的)
#include <iostream>
#include <algorithm>
using std::cout;
using std::endl;
class CArray {
public:
template <size_t S>
constexpr CArray(const int (&e)[S]) : els(&e[0]), sz(S) {}
const int* begin() const { return els; }
const int* end() const { return els + sz; }
private:
const int* els;
size_t sz;
};
const CArray gbl_arr{{3,2,1}};
int main() {
CArray arr{{1,2,3}};
cout << "Global size: " << std::distance(gbl_arr.begin(), gbl_arr.end()) << endl;
for (auto i : gbl_arr) {
cout << i << endl;
}
cout << "Local size: " << std::distance(arr.begin(), arr.end()) << endl;
for (auto i : arr) {
cout << i << endl;
}
return 0;
}
样本输出:
Global size: 3
32765
0
0
Local size: 3
1
2
3
在这种情况下,“局部”变量是正确的,但“全局”不是,应该是 3,2,1。
解决方案
我认为问题在于您的初始化正在创建一个临时对象,然后在该数组被销毁后存储一个指向该数组的指针。
const CArray gbl_arr{{3,2,1}};
调用上述构造函数时,传入的参数仅为调用本身创建,但 gbl_arr 在其生命周期结束后引用它。改成这样:
int gbl_arrdata[]{3,2,1};
const CArray gbl_arr{gbl_arrdaya};
它应该可以工作,因为它引用的数组现在与引用它的对象具有相同的生命周期范围。
推荐阅读
- asp.net - 如何在启动时使用 API 加载 Ninject
- xml - XSLT:处理 TEI 里程碑元素
- javascript - 图像选择在添加/删除字段中无法正常工作
- python - 无监督学习:离散时间序列的异常检测
- angular - 如何在 Angular 项目中创建具有类别/子类别/文章 slug 的 SEO 友好 URL?
- reactjs - React.js 根据状态中的 id 存储多个 datepicker 日期
- python-3.x - 在 Jupyter 笔记本中导入根目录的问题
- html - 抓取问题:“检查元素”不同于“查看页面源”
- javascript - Symfony 4 - PHP 将多维数组转换为 javascript
- reactjs - 运行函数和重定向