【问题标题】:Treat plain old data array as std::array [duplicate]将普通旧数据数组视为 std::array [重复]
【发布时间】:2018-02-16 09:25:00
【问题描述】:

我们有一个庞大的代码库,主要写在C。我们做了很多数值线性代数。

C 中,我们使用double*,长度为3 来建模3d 矢量。

C++ 中,我们使用std:array<double,3> 来建模3d 矢量。

我们有一个小的模板库来重载很多操作符,比如

template <class T, size_t N>
std::array<T, N> operator+(const std::array<T, N> &array1, const std::array<T, N> &array2) {
    std::array<T, N> a;
    for (size_t i = 0; i < N; i++) {
        a[i] = array1[i] + array2[i];
    }
    return a;
}

问题来了,当我们需要从CC++ 时(反过来也没问题,因为我们可以使用 .data() 方法来访问对齐的内存)。我不喜欢复制每个类似 c 的 3d 矢量,因为这在数值上会很昂贵。

我可以将 pod 数组视为 std::array 吗?或者有没有办法以不分配新内存但使用 pod 数组的内存的方式初始化 std::array?

我正在考虑使用guideline support library中的gsl::span,但我想知道是否有更好的解决方案。

【问题讨论】:

  • C 变体是数组 (double[3]) 还是动态分配 (malloc(3*sizeof(double))?在第一种情况下,您可能想看看array_view

标签: c++ memory-management stdarray


【解决方案1】:

您可以简单地投射:

double* c_array; // assign to whatever you like, length 3 or more
auto cpp_array = reinterpret_cast<std:array<double,3>*>(c_array);

这是可行的,因为std::array 绝对是一个包含单个 C 数组的结构。

【讨论】:

  • 我同意这将适用于标准库的每个合理实现,但标准中没有任何东西可以保证它,对吧? std::array 的一些实现可能会在实际数组之前添加一些额外的调试字段...
  • 我怀疑这是未定义的行为。是的,std::array&lt;T,N&gt;包含T[N]。这并不意味着它 T[N]。通过不兼容类型的表达式访问对象是 UB。
  • @michalsrb:不,std::array 不能包含额外的调试字段。这样做不仅没有什么可调试的,而且广泛使用 std::array 以要求它在内部是一个简单的数组,这永远不会允许这样的实现成功(意思是,有用户)。
  • @JohnZwinck:我可以想象你可以在std::array 上调试的东西。例如,标准库的调试版本可以在 std::array 中包含的数组之前和之后添加一个金丝雀字段,并在每种方法中测试它们以检测越界写入。这是合理的做法。它不会破坏有效的程序,但会破坏带有 reinterpret_cast 的程序。
猜你喜欢
  • 2021-05-26
  • 1970-01-01
  • 2017-02-11
  • 2012-04-18
  • 2014-08-31
  • 2021-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多