C++ constexpr 构造函数初始化垃圾值

C++ constexpr constructor initializes garbage values

我想要一个简单的 class 来封装一个指针和一个大小,我认为就像 C++20 的 std::span 一样。我正在使用 C++(准确地说是 g++ 11.2.1)

我想要它,这样我就可以拥有一些常量的模块级数据数组,而不必计算每个数组的大小。

但是我的实现 'works' 只是有时,依赖于优化标志和编译器(我在 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

在这种情况下,'local' 变量是正确的,但 'global' 不正确,应该是 3,2,1。

我认为问题是你的初始化是创建一个临时数组,然后你在它被销毁后存储指向该数组的指针。

const CArray gbl_arr{{3,2,1}};

调用上述构造函数时,传入的参数仅为调用本身创建,但 gbl_arr 在其生命周期结束后引用它。更改为:

int gbl_arrdata[]{3,2,1};
const CArray gbl_arr{gbl_arrdaya};

它应该可以工作,因为它引用的数组现在与引用它的对象具有相同的生命周期范围。